👉🏻 회원가입 및 로그인과 관련된 기능입니다.
These are features related to sign-up and login.
👉🏻 myapp27은 팔로우,팔로워 리스트 기능을 구현합니다.
myapp27 implements features for the following and followers lists.
👉🏻 팔로우와 팔로워 리스트는 프로필을 클릭하면 볼 수 있습니다.
You can view the lists of people you follow and your followers by clicking on the profile.
👉🏻 전체 코드는 깃허브에서 확인 할 수 있습니다.
You can find the full code on GitHub.
https://github.com/gideonslife01/flm-nextjs
📁 전체 프로젝트 구조 / Overall Project Structure
myapp project/
├── app/ (Next.js App Router)
│ ├── .well-known/webfinger/route.ts -> webfinger
│ ├── api/follow/route.ts -> Follow API(temporary)
│ ├── api/announce/route.ts -> Boost(Announcement)
│ ├── api/like/route.ts. -> Like API
│ ├── api/posts/route.ts -> Writing API
│ ├── api/timeline/route.ts -> Timeline API
│ ├── api/v1/instance/route.ts -> auth
│ ├── api/v1/apps/route.ts. -> auth
│ ├── api/v1/accounts/verify_credentials/route.ts -> auth
│ ├── api/v1/statuses/route.ts -> Write Post
│ ├── api/v1/timelines/home/route.ts -> timeline
│ ├── oauth/authorize/route.ts -> auth
│ ├── oauth/token/route.ts -> auth
│ ├── api/v1/search/home/route.ts -> search
│ ├── api/v2/search/home/route.ts -> search
│ ├── api/v1/accounts/[id]/followers/route.ts -> followers
│ ├── api/v1/accounts/[id]/following/route.ts -> following
│ ├── users/[username]/
│ │ ├── statuses/[id]/route.ts -> Indivisual Post
│ │ ├── route.ts -> Acotr Information
│ │ ├── followers/route.ts -> Followers List
│ │ ├── following/route.ts -> Following List
│ │ ├── inbox/route.ts -> Inbox
│ │ └── outbox/route.ts -> outbox
│ ├── usersui/[username]/
│ │ ├── page.tsx -> Timeline UI
│ │ └── _components/themes/
│ │ ├── themeex/ThemeexTheme.tsx -> Example Theme
│ │ ├── pinafore/PinaforeTheme.tsx -> Theme 1
│ │ ├── mastodon/MastodonTheme.tsx -> Theme 2
│ │ └── minimal/MinimaltTheme.tsx -> Theme 3
│ ├── layout.tsx, page.tsx, globals.css
│ └── favicon.ico
├── lib/
│ ├── theme.tsx -> Theme Provider
│ ├── watchThemes.ts -> Check real-time theme changes
│ ├── auth.ts -> Authentication, User Management
│ ├── ap.ts -> Follow,Undo,Create,Likes,Announce
│ └── db.ts -> DB connection
├── data/
│ ├── keys/userIDs/ -> private.pem, public.pem(New)
│ └── keys/ -> private.pem, public.pem(legacy)
├── data.sqlite -> Database(1/3)
├── data.sqlite-wal -> Database(2/3)
├── data.sqlite-shm -> Database(3/3)
├── Caddyfile -> https
├── instrumentation.ts -> Background Server
└── package.json
📁 프로젝트 시작 / Project Start
📁 라우트 추가 및 코드 수정 / Add routes and modify code
✔️ 팔로워 / follower
— 신규 추가된 라우트 / Newly added routes
— app/api/v1/accounts/[id]/followers/route.ts
/ ✅ myapp37 - followers API
// /api/v1/accounts/:id/followers
import { NextResponse } from 'next/server';
import db from '@/lib/db';
const DOMAIN = process.env.DOMAIN || 'aloy-horizon.duckdns.org';
function parseActor(actor: string, idx: number) { ... }
export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) { ... }
export async function OPTIONS() { ... }
✔️ 팔로잉 / following
— 신규 추가된 라우트 / Newly added routes
— app/api/v1/accounts/[id]/following/route.ts
// ✅ myapp37 - following API
// /api/v1/accounts/:id/following
import { NextResponse } from 'next/server';
import db from '@/lib/db';
const DOMAIN = process.env.DOMAIN || 'aloy-horizon.duckdns.org';
function parseActor(actor: string, idx: number) { ... }
export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) { ... }
export async function OPTIONS() { ... }
✔️ pinafore에서 팔로워,팔로잉 목록은 urlencode라서 코드 수정
Modified the code because the follower and following lists in Pinafore are URL-encoded.
— app/api/v1/apps/route.ts
import { NextResponse } from 'next/server';
import db from '@/lib/db';
import { randomUUID } from 'crypto';
const DOMAIN = process.env.DOMAIN || 'aloy-horizon.duckdns.org';
export async function POST(req: Request) {
try {
... ...
const contentType = req.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
const body = await req.json();
clientName = body.client_name || 'Unknown';
redirectUris = body.redirect_uris || body.redirect_uri || '';
scopes = body.scopes || 'read write follow';
website = body.website || '';
}else{
// form-urlencoded! Pinafore!가! 이걸로! 보냄!
//
const text = await req.text();
const params = new URLSearchParams(text);
clientName = params.get('client_name') || 'Unknown';
redirectUris = params.get('redirect_uris') || params.get('redirect_uri') || '';
scopes = params.get('scopes') || 'read write follow';
website = params.get('website') || '';
}
... ...
// ✅ Pinafore가 기대하는 응답!
// Pinafore expects this response!
return NextResponse.json({
id: clientId, // Pinafore는 id도 확인 / Pinafore also checks id
name: clientName,
website: website,
redirect_uri: redirectUris,
client_id: clientId,
client_secret: clientSecret,
vapid_key: '' // push용, 없어도 됨 / for push, not required
});
} catch (e) {
console.error('apps 에러 / apps error:', e);
//return NextResponse.json({ error: String(e) }, { status: 500 });
// ✅ myapp37 - 에러나도 일단 성공으로 리턴 / Return a success status for now, even if an error occurs.
return NextResponse.json({
id: '1',
name: 'Pinafore',
website: null,
redirect_uri: 'https://pinafore.social/settings/instances/add',
client_id: 'pinafore_client_id',
client_secret: 'pinafore_client_secret',
vapid_key: null,
}, {
headers: { 'Access-Control-Allow-Origin': '*' }
});
}
}
✔️ Notifications
— 신규 추가된 라우트 / Newly added routes
— app/api/v1/notifications/route.ts
// ✅ myapp37 - myapp/api/notifications/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
// 아직! 구현 안 함! 빈 배열! / Not yet! Not implemented! Empty array!
return NextResponse.json([], {
headers: { 'Access-Control-Allow-Origin': '*' }
});
}
export async function OPTIONS() {
return new NextResponse(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}
});
}
📁 테스트 / Test
✔️ 로그인 후 프로필에서 FOLLOWS와 FOLLOW를 클릭하면 리스트를 볼 수 있습니다.
After logging in, you can view the lists by clicking on “FOLLOWS” and “FOLLOW” in your profile.
✔️ 팔로우 / Follows

✔️ 팔로워 / Followers

요한복음 8장 32절 / John 8:32
“그리고 너희는 진리를 알게 될 것이며, 진리가 너희를 자유롭게 할 것이다.”
“Then you will know the truth ,and the truth will set you free”