[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

📁 전체 프로젝트 구조 / 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