316 lines
8.5 KiB
Markdown
316 lines
8.5 KiB
Markdown
# Approval & Publishing Workflow Plan
|
|
|
|
## Summary
|
|
|
|
This plan covers the implementation of approval, publishing, scheduling, preview, versioning, audit logging, and notification support for:
|
|
|
|
- `announcements`
|
|
- `online-lessons`
|
|
|
|
The goal is to extend the current simple `draft/published/archived` model into a controlled workflow without breaking the project's existing Auth.js, Drizzle, route-handler, and TanStack Query patterns.
|
|
|
|
## Current Repo Reality
|
|
|
|
### Announcements
|
|
|
|
- Current status model: `draft | published | archived`
|
|
- Employee visibility is currently based on:
|
|
- `status = published`
|
|
- `start_date <= now`
|
|
- `end_date is null or end_date >= now`
|
|
- HRD and super admin can manage records through existing create/update/delete endpoints
|
|
- Publish and archive are currently direct status updates
|
|
- Notifications already exist for published announcements
|
|
- Audit logging already exists for create, update, publish, archive
|
|
|
|
### Online Lessons
|
|
|
|
- Current status model: `draft | published | archived`
|
|
- Employee visibility is currently based on `is_published = true`
|
|
- Publish is currently a direct status change plus `isPublished/publishedAt`
|
|
- Audit logging and notifications are not yet as complete as announcements
|
|
|
|
### Roles
|
|
|
|
- Current business roles in code:
|
|
- `IT`
|
|
- `HRD`
|
|
- `EMPLOYEE`
|
|
- Current elevated system role:
|
|
- `super_admin`
|
|
- There is no dedicated `HRD_MANAGER` role in the current schema or auth helper layer
|
|
|
|
### Scheduler
|
|
|
|
- No existing publish scheduler or cron pattern was found in the repo
|
|
- Scheduled publish must therefore be introduced deliberately and in a way that matches deployment constraints
|
|
|
|
## Key Gaps To Solve
|
|
|
|
1. Status enums are too limited for the requested workflow.
|
|
2. No first-class review metadata exists for announcements or online lessons.
|
|
3. No versioning structure exists for either module.
|
|
4. No `HRD Manager` capability exists in the current role model.
|
|
5. No scheduled publish executor exists.
|
|
6. Employee visibility rules differ between announcements and online lessons and need to be normalized around `Published + current version`.
|
|
|
|
## Proposed Design Decisions
|
|
|
|
### 1. Workflow status model
|
|
|
|
Use the same workflow vocabulary for both modules:
|
|
|
|
- `draft`
|
|
- `pending_approval`
|
|
- `approved`
|
|
- `scheduled`
|
|
- `published`
|
|
- `rejected`
|
|
- `archived`
|
|
|
|
### 2. Versioning model
|
|
|
|
For both `announcements` and `online_lessons`, add:
|
|
|
|
- `version`
|
|
- `parent_id`
|
|
- `is_current`
|
|
|
|
Behavior:
|
|
|
|
- Records not yet published can be edited in place
|
|
- Once a record has been published, editing must create a new draft revision
|
|
- Only one version per logical record can be `is_current = true`
|
|
- Employee-facing queries must only show:
|
|
- `status = published`
|
|
- `is_current = true`
|
|
|
|
### 3. Permission model
|
|
|
|
Use the current auth model as the base and extend it with app-owned permission checks instead of inventing client-only gates.
|
|
|
|
Recommended interpretation for implementation:
|
|
|
|
- `super_admin`
|
|
- full override for all workflow actions
|
|
- `HRD`
|
|
- current generic HRD behavior should be split by permission, not by a brand new auth system
|
|
|
|
Recommended incremental approach:
|
|
|
|
- keep existing `businessRole` values
|
|
- introduce fine-grained permission checks for content workflow actions
|
|
- model `HRD Manager` as a permission-capable HRD user, not as a breaking replacement of the current role model
|
|
|
|
Suggested permission flags:
|
|
|
|
- `content:submit`
|
|
- `content:approve`
|
|
- `content:publish`
|
|
- `content:archive`
|
|
- `content:schedule`
|
|
- `content:manage_all`
|
|
|
|
This avoids rewriting the entire auth model while still supporting the requested behavior.
|
|
|
|
### 4. Scheduled publish
|
|
|
|
Because no scheduler pattern currently exists, implement in two layers:
|
|
|
|
- data model and API support first
|
|
- a server-triggerable publish processor second
|
|
|
|
Recommended first implementation:
|
|
|
|
- add a reusable server function that publishes due scheduled records
|
|
- expose an internal route handler or job entrypoint for future cron integration
|
|
|
|
This keeps the business logic testable even before infrastructure automation is added.
|
|
|
|
## Database Changes
|
|
|
|
### Announcements
|
|
|
|
Extend `announcements` with:
|
|
|
|
- `version`
|
|
- `parent_id`
|
|
- `is_current`
|
|
- `submitted_by`
|
|
- `submitted_at`
|
|
- `approved_by`
|
|
- `approved_at`
|
|
- `rejected_by`
|
|
- `rejected_at`
|
|
- `rejected_reason`
|
|
- `scheduled_publish_at`
|
|
- `published_by`
|
|
- `published_at`
|
|
- `unpublished_by`
|
|
- `unpublished_at`
|
|
- `archived_by`
|
|
- `archived_at`
|
|
|
|
Replace enum values to support the workflow states.
|
|
|
|
### Online Lessons
|
|
|
|
Extend `online_lessons` with the same workflow and versioning fields.
|
|
|
|
Review whether `is_published` should be retained temporarily as a derived compatibility field during migration or removed after full workflow migration.
|
|
|
|
## Backend Work Plan
|
|
|
|
### Phase 1. Shared workflow foundation
|
|
|
|
- add new enums to `src/db/schema.ts`
|
|
- add migration for announcements and online lessons
|
|
- add shared permission helpers for content workflow
|
|
- extend audit action constants
|
|
- extend notification service helpers
|
|
|
|
### Phase 2. Announcement workflow backend
|
|
|
|
- update list/detail access rules
|
|
- update create/edit behavior
|
|
- add submit for approval action
|
|
- add approve/reject action
|
|
- add publish now action
|
|
- add schedule publish action
|
|
- add cancel schedule action
|
|
- add unpublish action
|
|
- add archive action
|
|
- add create revision action for published records
|
|
|
|
### Phase 3. Online lesson workflow backend
|
|
|
|
- apply the same workflow actions and rules
|
|
- align employee visibility with `published + is_current`
|
|
|
|
### Phase 4. Scheduled publish processor
|
|
|
|
- create reusable processor for due announcements
|
|
- create reusable processor for due online lessons
|
|
- add internal route or task entrypoint for future cron wiring
|
|
|
|
## Frontend Work Plan
|
|
|
|
### Announcements
|
|
|
|
- refactor form actions:
|
|
- `Save Draft`
|
|
- `Submit for Approval`
|
|
- `Preview`
|
|
- remove direct publish/archive controls from HRD staff flows
|
|
- add manager/admin action controls based on status
|
|
- add revision flow for published records
|
|
- add preview route/view
|
|
|
|
### Online Lessons
|
|
|
|
- refactor form actions to match announcement workflow
|
|
- replace direct publish/archive actions with workflow-aware actions
|
|
- add preview and revision behavior
|
|
|
|
### HRD Manager Dashboard
|
|
|
|
Introduce a dedicated manager workflow page that groups both modules by status:
|
|
|
|
- pending approval
|
|
- approved waiting publish
|
|
- scheduled
|
|
- published
|
|
- rejected
|
|
- archived
|
|
|
|
Recommended implementation path:
|
|
|
|
- start with one page under dashboard
|
|
- use tabs or segmented sections
|
|
- reuse existing table/list patterns instead of inventing a new shell
|
|
|
|
## API Surface To Add
|
|
|
|
Recommended route pattern:
|
|
|
|
- `POST /api/announcements/[id]/submit`
|
|
- `POST /api/announcements/[id]/approve`
|
|
- `POST /api/announcements/[id]/reject`
|
|
- `POST /api/announcements/[id]/publish`
|
|
- `POST /api/announcements/[id]/schedule`
|
|
- `POST /api/announcements/[id]/cancel-schedule`
|
|
- `POST /api/announcements/[id]/unpublish`
|
|
- `POST /api/announcements/[id]/archive`
|
|
- `POST /api/announcements/[id]/revision`
|
|
|
|
Mirror the same shape for `online-lessons`.
|
|
|
|
Keep these actions separate from generic `PATCH` to preserve explicit permission checks and status transitions.
|
|
|
|
## Audit And Notification Plan
|
|
|
|
### Audit
|
|
|
|
Extend audit coverage for both modules:
|
|
|
|
- submit
|
|
- approve
|
|
- reject
|
|
- publish
|
|
- schedule
|
|
- cancel schedule
|
|
- unpublish
|
|
- archive
|
|
- create revision
|
|
|
|
### Notifications
|
|
|
|
Reuse the existing notification service.
|
|
|
|
Add notification types/messages for:
|
|
|
|
- submitted for approval
|
|
- approved
|
|
- rejected
|
|
- scheduled
|
|
- published
|
|
- unpublished
|
|
- archived
|
|
|
|
## Risks
|
|
|
|
1. Role model ambiguity:
|
|
`HRD Manager` does not yet exist as a first-class role, so permission-based implementation is safer than role explosion.
|
|
|
|
2. Scheduler infrastructure:
|
|
automatic scheduled publish cannot be considered complete until deployment wiring is agreed.
|
|
|
|
3. Versioning migration:
|
|
existing published records must be backfilled carefully so they become `version = 1` and `is_current = true`.
|
|
|
|
4. UI complexity:
|
|
if both modules implement bespoke workflow UIs separately, the code may drift. Shared status/action utilities should be introduced where practical.
|
|
|
|
## Implementation Order
|
|
|
|
1. Add workflow plan document
|
|
2. Add schema changes and migration
|
|
3. Add shared workflow permission helpers
|
|
4. Upgrade announcement backend
|
|
5. Upgrade online lesson backend
|
|
6. Add preview and revision flows
|
|
7. Add manager dashboard
|
|
8. Add scheduled publish processor entrypoint
|
|
9. Add docs and implementation report
|
|
|
|
## Immediate Next Step
|
|
|
|
Start with schema and contract design for:
|
|
|
|
- workflow statuses
|
|
- versioning columns
|
|
- approval metadata
|
|
- publish metadata
|
|
|
|
Then implement announcement backend first as the reference module, followed by online lessons.
|