[nextjs]SNS Server-36(myapp46)Β 

πŸ‘‰πŸ» myapp46μ—μ„œλŠ” myapp46μ—μ„œ μΆ”κ°€λœ μ‚­μ œ λ²„νŠΌμ„ μ΄μš©ν•΄μ„œ κΈ€ μ‚­μ œ κΈ°λŠ₯을 μ™„λ£Œν•©λ‹ˆλ‹€.
In myapp46, the post deletion function is implemented using the delete button added in myapp46.

πŸ‘‰πŸ» 둜컬 μ„œλ²„μ˜ 글을 μ‚­μ œμ‹œ 리λͺ¨νŠΈ μ„œλ²„μ˜ κΈ€ μ‚­μ œκ°€ μ™„λ£Œλ˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.
Verify that deleting a post on the local server also completes the deletion of the post on the remote server.

πŸ‘‰πŸ» ν…ŒμŠ€νŠΈ 기쀀은 gotosocialμ„œλ²„λ₯Ό κΈ°μ€€μœΌλ‘œ ν•©λ‹ˆλ‹€.
The testing is based on the GoToSocial server.

πŸ‘‰πŸ» λ§ˆμŠ€ν† λˆ μ„œλ²„λŠ” ν˜„μž¬ ν™•μΈν•˜κΈ° νž˜λ“  뢀뢄이 μžˆμ–΄μ„œ μ œκ°€ ꡬ좕해놓은 gotosocialκ³Ό 연동을 λ¨Όμ € ν…ŒμŠ€νŠΈ ν•©λ‹ˆλ‹€.
Since there are aspects of the Mastodon server that are currently difficult to verify, I am first testing the integration with the GoToSocial instance I have set up.

πŸ‘‰πŸ» λ§ˆμŠ€ν† λˆ μ„œλ²„λŠ” ν˜„μž¬ μ„œλ²„ 둜그만 ν™•μΈν•©λ‹ˆλ‹€.
The Mastodon server currently only checks server logs.

πŸ‘‰πŸ» 전체 μ½”λ“œλŠ” κΉƒν—ˆλΈŒμ—μ„œ 확인 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
You can find the full code on GitHub.

https://github.com/gideonslife01/flm-nextjs

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/followinglist/route.ts  -> followinglist API
β”‚   β”œβ”€β”€ api/followerslist/route.ts  -> followerslist 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
β”‚   β”œβ”€β”€ api/auth/signup/route.ts        -> Signup
β”‚   β”œβ”€β”€ api/auth/login/route.ts         -> Login
β”‚   β”œβ”€β”€ api/auth/logout/route.ts        -> Logout
β”‚   β”œβ”€β”€ api/auth/refresh/route.ts       -> Refresh Token
β”‚   β”œβ”€β”€ api/cleanup-orphan/route.ts     -> post,outbox clean up
β”‚   β”œβ”€β”€ api/auth/me/route.tsx           -> Login Check
β”‚   β”œβ”€β”€ auth/signup/page.tsx            -> Signup UI
β”‚   β”œβ”€β”€ auth/signup/page.tsx            -> Login UI
β”‚   β”œβ”€β”€ 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(Server, 404)
β”‚   β”‚   β”œβ”€β”€ ClientPage.tsx.        -> Timeline UI(Client,Call Active Themes)
β”‚   β”‚   └── _components/themes/
β”‚   β”‚       β”œβ”€β”€ themeex/ThemeexTheme.tsx   -> Example Theme
β”‚   β”‚       β”œβ”€β”€ pinafore/PinaforeTheme.tsx -> Theme 1
β”‚   β”‚       β”œβ”€β”€ pinafore/FollowersList.tsx -> Theme 1, FollowersList
β”‚   β”‚       β”œβ”€β”€ pinafore/FollowingList.tsx -> Theme 1, FollowingList
β”‚   β”‚       β”œβ”€β”€ pinafore/NotificationsList.tsx -> Theme 1, NotificationsList
β”‚   β”‚       β”œβ”€β”€ 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 route

βœ”οΈ app/api/cleanup-orphan/route.ts

— 아직은 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 라우트 μž…λ‹ˆλ‹€.
This is a route that is not currently in use.

— μ²­μ†Œμš© 라우트,ouboxν…Œμ΄λΈ”κ³Ό postsν…Œμ΄λΈ”μ˜ λ‚΄μš©μΌ μΌμΉ˜ν•˜μ§€ μ•ŠλŠ” 경우 μ‚­μ œ
Delete records where the contents of the oubox table and the posts table do not match (cleanup routine).

— oubox λ‹€λ₯Έ μ„œλ²„λ‘œ 보낸 κΈ€ posts λ‚΄κ°€ μž‘μ„±ν•œ κΈ€
Outbox / Posts sent to other servers / Posts I wrote

πŸ“ 이전 라우트 μž‘λ™ ν…ŒμŠ€νŠΈ(μ‚¬μ „ν…ŒμŠ€νŠΈ)

βœ”οΈ λ‘œμ»¬μ„œλ²„, 터미널 ν…ŒμŠ€νŠΈ

# κΈ€ μ“°κΈ° - 둜컬 (둜컬 μ„œλ²„ UIμ „μš© ,outbox 7둜 증가 + νŒ”λ‘œμ›Œλ“€μ—κ²Œ 배달)
# Write Post - Local (Local server UI only; increment outbox to 7 + deliver to followers)

curl -X POST https://aloy-horizon.duckdns.org/api/posts \
  -H "Content-Type: application/json" \
  -d '{"username":"user1","content":"Hello local UI #apiposts myapp46"}'

# κΈ€ μˆ˜μ •(λ‘œμ»¬λ§Œκ°€λŠ₯, κ΅¬ν˜„μ˜ˆμ •, 라우트있음)
# Modify post (local-only, pending implementation, route exists)

curl -X PUT https://aloy-horizon.duckdns.org/api/posts \
  -H "Content-Type: application/json" \
  -d '{"username":"user1","id":"xxx","content":"μˆ˜μ •λœ λ‚΄μš©/Revised content"}'


# κΈ€ μ‚­μ œ  / Delete Posts(myapp30)
# myapp30 λΆ€ν„° GET방식도 μ§€μ›ν•©λ‹ˆλ‹€.
# 1) POST

curl -X DELETE https://aloy-horizon.duckdns.org/api/posts \
 -H "Content-Type: application/json" \
 -d '{"username":"user1","id":"e6c99652-572f-491a-9e61-05e67b0d58fc"}'

# 2) GET

curl -X DELETE "https://aloy-horizon.duckdns.org/api/posts?id=117204066261760455&username=user1"

βœ”οΈ ν„°λ―Έλ„μ—μ„œ λ‚΄ μ„œλ²„μ— κΈ€μ“°κΈ° μ‹€ν–‰
Run the post-writing command on my server from the terminal.

— κ³ νˆ¬μ†Œμ…œμ— κΈ€ 배달 μƒνƒœ 확인
Check post delivery status on GoToSocial

% curl -X POST https://aloy-horizon.duckdns.org/api/posts \
  -H "Content-Type: application/json" \
  -d '{"username":"user1","content":"Hello local UI #apiposts myapp46"}'

{"id":"4bf8ddd5-ac78-41a2-9e97-37a36aacdeb3","content":"Hello local UI #apiposts myapp46","created_at":"2026-09-22 23:35:53","username":"user1"}
% 

βœ”οΈ λ§ˆμŠ€ν† λˆμ—μ„œ κΈ€μ“°κ³  λ‚΄ μ„œλ²„λ‘œ λ°°λ‹¬λ˜λŠ”μ§€ 확인
Write a post on Mastodon and check if it gets delivered to my server.

# μ„œλ²„ 둜그 / Server Log
πŸ“© [user1] INBOX: Create https://mastodon.social/ap/users/117193449750714993 https://mastodon.social/ap/users/117193449750714993/statuses/117317371254499150/activity
πŸ”‘ μΊμ‹œ μ—†μŒ! / No cache, Fetch! https://mastodon.social/ap/users/117193449750714993
πŸ”‘ Actor publicKey κ°€μ Έμ˜€κΈ° / Get Actor publickey: https://mastodon.social/ap/users/117193449750714993 as user1
πŸ” Signed GET -> https://mastodon.social/ap/users/117193449750714993 as user1
πŸ” 검증 signingString / verification signingString: host: aloy-horizon.duckdns.org
date: Tue, 22 Sep 2026 23:50:21 GMT
content-type: application/activity+json
digest: SHA-256=BGiclF18OTj4d24GcMLm2ezW9dr1SMoUu1KegaQg5Ho=
(request-target): post /users/user1/inbox
βœ… μ„œλͺ… 검증 성곡! / Signature verification successful!
βœ… μ„œλͺ… 검증 성곡 / Signature verification successful, actor: https://mastodon.social/ap/users/117193449750714993
πŸ“ [user1] μƒˆ κΈ€ 도착 from https://mastodon.social/ap/users/117193449750714993
βœ… inbox_posts μ €μž₯/ save inbox_posts: 117317371254499150
 POST /users/user1/inbox 202 in 874ms (next.js: 13ms, proxy.ts: 11ms, application-code: 850ms)

# λ‚΄ μ„œλ²„ DB / My Server DB
sqlite> select actor,content,username from inbox_posts;
https://freelifemakers.com/users/user1|<p>inbox_posts table test</p>|user1
https://freelifemakers.com/users/user1|<p>actor test</p>|user1
https://freelifemakers.com/users/user1|<p>likes test</p>|user1
https://freelifemakers.com/users/user1|<p>boost delivery test!!</p>|user1
https://freelifemakers.com/users/user1|<p>Boots Button Test</p>|user1
https://freelifemakers.com/users/user1|<p>Favorite TEst</p>|user1
https://mastodon.social/ap/users/117193449750714993|<p>Hello Mastodon!!!</p>|user1
https://mastodon.social/ap/users/117193449750714993|<p>mastodon boost test</p>|user1
https://mastodon.social/ap/users/117193449750714993|<p>mastodon ,ally,user1 posts delete test</p>|user1
https://mastodon.social/ap/users/117193449750714993|<p>search profile test!!</p>|user1
https://mastodon.social/ap/users/117193449750714993|<p>follow and search profile test</p>|user1
https://mastodon.social/ap/users/117193449750714993|<p>myapp46 post delivery test from mastodon to aloy</p>|user1
sqlite> 

πŸ“ μ½”λ“œμˆ˜μ • / Code Modification

βœ”οΈ app/api/posts/route.ts

— κΈ€ λ°°λ‹¬μ‹œ outbox에도 μ €μž₯
Save to outbox when delivering text

  // βœ… myapp46 - insert into oubox
  try {
  db.prepare('CREATE TABLE IF NOT EXISTS outbox (id TEXT PRIMARY KEY, type TEXT, actor TEXT, object TEXT, created_at INTEGER)').run();
  db.prepare('INSERT INTO outbox (id, type, actor, object, created_at) VALUES (?,?,?,?,?)')
    .run(id, 'Create', `https://${DOMAIN}/users/${username}`, JSON.stringify(note), Date.now());
} catch {}

πŸ“ ν…ŒμŠ€νŠΈ / Test

curl -X POST https://aloy-horizon.duckdns.org/api/posts \
  -H "Content-Type: application/json" \
  -d '{"username":"user1","content":"myapp46 pos delivery and delete test"}'

βœ”οΈ ν„°λ―Έλ„μ—μ„œ κΈ€μ“°κΈ° / Writing in the terminal

write post

βœ”οΈ λ‘œμ»¬μ„œλ²„ / Local Server

local server

βœ”οΈ 리λͺ¨νŠΈμ„œλ²„ / Remote Server

— gotosocial,freelifemakers.com/@user1

gotosocial,freelifemakers.com/@user1

βœ”οΈ μ„œλ²„ 둜그 / Server Log

— mastodon , gotosocial 202

Server Log

μš”ν•œλ³΅μŒ 8μž₯ 32절 / John 8:32

“그리고 λ„ˆν¬λŠ” 진리λ₯Ό μ•Œκ²Œ 될 것이며, 진리가 λ„ˆν¬λ₯Ό 자유둭게 ν•  것이닀.”

“Then you will know the truth ,and the truth will set you free”

Leave a Reply