-
Session/Authentication
/api/captcha/verify(POST): verifies captcha token (dev secret:i-am-human). Returnsnext_pagepointing toapp.htmlorauth.htmldepending on if a valid session exists./api/auth/login(POST): login bylogin_username&passwordand optionaldevice_label. Returns signed cookie set viaSet-Cookieand a redirect payload./api/auth/register,/api/auth/reset,/api/auth/pin,/api/auth/logout,/api/auth/logout-all: follow the flows described inSPECS.md. All expect JSON body and sendapplication/jsonresponses wrapped insideApiEnvelope.
-
Chat/Discussion
/api/chats/message(POST): send chat message. Requiresuser_id,chat_id,chat_type,body. Rate limited (1 msg / 3s) and enforces mention/permission rules./api/chats/message/edit(POST): sender-only edit within 300s ofcreated_at; body trimmed; re-parses mentions; broadcastschat.messagewithedited_at./api/chats/message/delete(POST): sender-only soft delete; body becomesMesaj silindi,deleted = true,mentions = []; broadcastschat.message./api/chats/dm-request(POST) &/api/chats/group(POST): DM request/group creation flows tied to authenticated user_id./api/discussion/post(POST) &/api/discussion/vote(POST): create posts or vote./api/discussion/list(GET) supportssortquery (hot,top,new)./api/community/mute(POST): mutes community notifications formute_minutes.
-
Notifications & Files
/api/notifications/list(GET): acceptsuser_id,cursor,limitand returns paged notifications (chronological cursor)./api/files/prepare(POST): validates file metadata before upload (checks MIME, size, permission level) and updates UI with readiness state./api/files/upload(POST multipart): acceptsuser_id,file_id, and the binary payload to persist the file content to disk; useFormData+Melt.uploadFilehelper.
-
Admin
/api/admin/overview,/api/admin/users,/api/admin/users/approve,/api/admin/users/status,/api/admin/users/reject,/api/admin/users/permission,/api/admin/rate-config,/api/admin/audit: endpoints for admin dashboard inadmin.html. All require admin privileges checked before servingadmin.html.
- Connection occurs at
/wsusing signed session cookie. Only authenticated sessions may connect. - Server emits
WsServerEvent::chat.message,WsServerEvent::discussion.post,WsServerEvent::discussion.vote,WsServerEvent::notification.created,WsServerEvent::admin.event, etc. Each handler receives apayloadobject tailored to the event (message DTOs, discussion posts, votes, notification records, admin metadata). - Client
Melt.startPresenceSocket(elementId)handles connection management, periodic ping, and reconnection with exponential backoff. The method internally manages timers to updatepresence-statusfields on the UI. - Extend
Melt.onWebSocketEventwith your own listeners (e.g., refresh discussion list ondiscussion.post, refresh notifications whennotification.createdfor the authenticated user, and highlight admin changes wheneveradmin.eventfires). Guardpayload.typeand the required identifiers before mutating UI state. - Future WebSocket improvements (see
EKSIK.mdsections 8 & 9) should add more event types if necessary.
- Session gating
- Begin at
index.html. The captcha gate posts to/api/captcha/verify. On success, follow thenext_pagefrom response for eitherapp.htmlorauth.html. - All subsequent pages rely on server-set HttpOnly cookies;
Melt.apiusescredentials: "same-origin"so cookies are sent automatically.
- Begin at
- Presence-driven UI
- Both
app.htmlandadmin.htmlcallMelt.startPresenceSocketto maintain a WebSocket link. UseMelt.onWebSocketEventto react to server broadcasts.
- Both
- Error handling
- APIs uniformly return
ApiEnvelope. Checkresult.okandresult.body.okbefore trustingresult.body.data. - WebSocket parsing issues are logged to console. Always guard
payload.type,payload.chat_id, andpayload.messagebefore mutating UI state, and keep updates idempotent so repeated broadcasts don't duplicate messages.
- APIs uniformly return
- File upload helper
- Use
Melt.uploadFile(file, { user_id, file_id })after/api/files/preparereturnsfile_id. The helper usesFormDatato send the binary payload and the required metadata, then returns anotherApiEnveloperesponse to confirm the upload succeeded.
- Use
{ "type": "chat.message", "payload": { "chat_id": "<uuid>", "chat_type": 1|2|3, "message": { "id": "<uuid>", "body": "text or Mesaj silindi", "sender_id": "<uuid>", "created_at": "2026-02-16T12:00:00Z", "edited_at": "2026-02-16T12:02:00Z|null", "deleted": false } } }