commit
This commit is contained in:
315
plans/approval-publishing-workflow-plan.md
Normal file
315
plans/approval-publishing-workflow-plan.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user