Admin Frame Status

status report
Generated May 14, 2026  ·  threads-api-v2 @ workspace
1
Migration
Report + bannedUntil
4
Admin modules
DTO/Input frame
1
Queue riêng
auto_remove_ban_queue
3
Checks
validate · generate · typecheck

Highlights


Change Ledger


AreaActionTechnical changeWhyRisk
prisma/schema.prismamodifiedAdded User.bannedUntil, ReportTargetType, ReportStatus, and Report.Gives the admin frame durable tables/fields without inventing service behavior yet.Med
prisma/migrations/20260514120000...addedAdds banned_until, report table, indexes, and reporter foreign key.Migration keeps database change explicit and reviewable.Med
report-management/dtoaddedExternal body DTO contains action and adminNote.These values come from HTTP body, so they belong in DTO, not internal input.Low
report-management/interfacesaddedModerateReportInput enriches DTO with reportId and adminId.Params/JWT values are internal context, not client body data.Low
report-management.repository.tsmodifiedReplaced no-op stub with create, findById, and updateById.Repository now only exposes DB operations. It does not decide what approve/hide/delete means.Low
report-management.service.tsmodifiedReturns frame response with report lookup and clear nextStep TODO.Keeps route usable while leaving core moderation orchestration for later service work.Low
user-management/dtoaddedExternal ban DTO accepts optional bannedUntil and durationHours.Both values are caller-provided request data, so they are DTO-level.Low
user-management/interfacesaddedInternal inputs add userId, adminId, normalized Date, and expired-ban update data.These values are enriched by params/JWT/job runtime.Low
user-management.repository.tsmodifiedAdded DB update methods for ban fields and expired banned users; selected bannedUntil in list users.Needed DB primitives for later service logic and hourly worker frame.Med
hashtag-trendingmodifiedAdded query DTO/input and repository query ordered by Topic.count desc.Turns the route from stub into a DB-backed frame with a normalized limit.Low
statisticsmodifiedAdded query DTO/input and repository aggregate/count queries for posts, users, reports, hashtags, and posts per day.Stats endpoint now has real DB reads, while shaping policy can still evolve in service later.Med
src/constants/queue.tsmodifiedAdded AUTO_REMOVE_BAN_QUEUE, AUTO_REMOVE_BAN_WORKER, and RUN_AUTO_REMOVE_BAN.Matches the existing queue constant pattern and keeps monitoring names stable.Low
auto-remove-ban produceraddedCreates a dedicated queue and registers an hourly repeat job with stable job id.Separate queue makes remove-ban jobs visible apart from like sync jobs.Med
workers/auto-remove-ban.worker.tsaddedConsumes RUN_AUTO_REMOVE_BAN, builds internal input, and calls the DB update hook.Worker frame is ready; final service flow can replace the direct call later.Med
queues/auto-remove-ban.queue.tsaddedAdds BullMQ QueueEvents logging for waiting/active/completed/failed.Follows the existing queue event file format for observability.Low
src/server.tsmodifiedInitializes auto-remove-ban repeat job after like sync scheduler init.Ensures scheduler registration happens at app startup using the repo's current pattern.Med
docs/index.htmlmodifiedAdded this report card, updated counts, and mapped an icon.Keeps the docs hub complete without deleting old docs.Low

DTO vs Internal Input


ModuleDTO: outside dataInput: enriched internal data
report-managementaction, adminNote from request body.reportId from params, adminId from JWT, plus body fields.
user-managementbannedUntil, durationHours from request body.userId from params, adminId from JWT, parsed Date.
hashtag-trendinglimit from query string.Normalized numeric limit with default 10.
statisticsstartDate, endDate from query string.Parsed optional Date range for DB aggregate queries.
auto-remove-bantriggeredBy, requestedAt from job payload.now, jobId, and normalized trigger metadata inside worker.

Name Glossary


NameDefinitionWhere it appears
bannedUntilTemporary-ban expiry time. If this Date is in the past, auto-remove-ban can move the user back to ACTIVE. If it is missing/null, the ban has no scheduled expiry in the current frame.User DTO, user input, Prisma users.banned_until
durationHoursRelative ban length sent by a caller. It is stored in input for later service logic to convert into bannedUntil.BanUserRequestDto, BanUserInput
adminIdAuthenticated admin user id from JWT context. This is not body data; it is internal metadata for future audit logs.Report and user-management inputs
adminNoteHuman explanation written by an admin while handling a report. Later service logic can persist it to reports.admin_note.Report DTO/input
actionRequested moderation action from outside: approve, hide_post, or delete_post. Repository receives only DB data; service will decide how this action maps to writes.Report DTO/input
targetTypeType of reported entity. Current allowed values are POST and USER.Prisma Report
targetIdIdentifier of the reported entity. It is a string so it can point to either a post public id or a user id depending on targetType.Prisma Report
ReportStatusModeration queue state: PENDING for new reports, RESOLVED for handled reports, DISMISSED for future reject/ignore flows.Prisma enum, stats repository
AutoRemoveBanJobDtoSerialized BullMQ payload saved in Redis. It is treated like external data because producer and worker communicate through the queue boundary.Auto-remove-ban producer/worker
AutoRemoveBanInput.nowWorker runtime Date used in the DB query bannedUntil < now.Auto-remove-ban worker input
triggeredBySource of the auto-remove-ban job. Currently scheduler; manual is reserved for future admin-triggered jobs.Auto-remove-ban job DTO/input
jobIdBullMQ id for the current job. Used only for logging/correlation.Auto-remove-ban worker input

Auto-Remove-Ban Queue Flow


server.ts initAutoRemoveBanJob() Producer repeat every 1h auto_remove_ban_queue QueueEvents logs Worker build input + DB hook
No per-user delayed job is added at ban time. Current frame uses one hourly scanner. If later service logic needs immediate delayed remove-ban per user, add that job at the end of the ban service after DB commit.

Removed or Deferred


Removed
No files were deleted. Stub response flags like implemented: false were removed from admin service responses where a clearer frame response now exists.
Deferred
Moderation decisions for approve, hide_post, and delete_post are not implemented yet. Add that orchestration in report-management.service.ts.
Deferred
durationHours is captured in DTO/input but not converted into bannedUntil yet. Add that rule in user-management.service.ts.
Deferred
Auto-remove-ban worker currently calls the repository DB hook directly. When the service flow is ready, move this call behind service orchestration and keep the worker as trigger/input builder.

Verification


CommandResultNotes
npx prisma validatePassedSchema loaded from prisma/schema.prisma and validated successfully.
npm run db:generatePassedPrisma Client v7.8.0 generated so TypeScript can see new model/enum fields.
npm run typecheckPassedtsc -p tsconfig.json --noEmit completed without errors.