ππ» 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

βοΈ λ‘컬μλ² / Local Server

βοΈ λ¦¬λͺ¨νΈμλ² / Remote Server
— gotosocial,freelifemakers.com/@user1

βοΈ μλ² λ‘κ·Έ / Server Log
— mastodon , gotosocial 202

μν볡μ 8μ₯ 32μ / John 8:32
“κ·Έλ¦¬κ³ λν¬λ μ§λ¦¬λ₯Ό μκ² λ κ²μ΄λ©°, μ§λ¦¬κ° λν¬λ₯Ό μμ λ‘κ² ν κ²μ΄λ€.”
“Then you will know the truth ,and the truth will set you free”