Appearance
Database Reference
Full schema reference for the PS Workflow PostgreSQL database (hosted on Neon via Prisma). All tables use db push — there is no migrations history, only the current schema.
Entity Relationship Diagram
Core Tables
Deliverable
The central record for a single sponsored content piece. One row per deliverable — created by the PS team from a Monday.com item and progresses through stages until COMPLETE.
| Field | Type | Notes |
|---|---|---|
id | Int | Primary key, auto-increment |
mondayItemId | String | The Monday.com item ID this deliverable maps to |
deliverableName | String | Full name from Monday (e.g. "Caleb Hammer YouTube Integration for SoFi") |
creatorName | String | Parsed from the Monday item name |
brandName | String | Parsed from the Monday item name |
stage | DeliverableStage | Current workflow stage — see Stage Enum below |
brandEmail | String | Effective email used for brand notifications (may be override in test mode) |
creatorEmail | String | Effective email used for creator notifications (may be override in test mode) |
brandEmailOverride | String? | Test-mode override email for brand |
creatorEmailOverride | String? | Test-mode override email for creator |
brandEmailReal | String? | Actual fetched brand email (always stored, regardless of test mode) |
creatorEmailReal | String? | Actual fetched creator email (always stored) |
testMode | Boolean | If true, test overrides are applied to all notifications |
psPerson | String | PS team member name (from Monday "Partnership Success" column) |
agent | String | Agent name (from Monday "Agent" column) |
platform | String? | Content platform (from Monday "Platform" column) — e.g. "YouTube", "LinkedIn", "Newsletter" |
payoutDate | String? | Payment date string from Monday's payout board |
contractUrl | String? | Google Drive link to the Creator Agreement (fetched from Monday files) |
adPosition | String? | Ad read position extracted from contract (async after creation) |
mode | String | "normal" or "manual_intervention". Set to manual_intervention when PS needs to step in. |
brandNote | String? | PS-added note visible to creator on the form |
talkingPointsLink | String? | Google Docs link to brand brief (set by brand in WAITING_ON_TALKING_POINTS) |
trackingLink | String? | Affiliate/tracking URL from brand |
descriptionText | String? | Approved video caption — shown verbatim to creator at posting time |
pinnedCommentText | String? | Approved pinned comment text |
adPlacement | String? | When in the video the sponsor segment should appear |
brandAssetLinks | String[] | Array of links to brand logos, b-roll, graphics |
otherRequirements | String? | Additional posting requirements fetched from Monday at approval time |
creatorCommChannel | String? | "email" or "slack" — from Airtable creator record |
creatorSlackChannelId | String? | Creator's Slack channel ID (for Slack-based creators) |
creatorSlackUserId | String? | Creator's Slack user ID |
brandCommChannel | String? | "email" or "slack" — from Copper brand company record |
brandSlackChannelId | String? | Brand's Slack channel ID |
brandSlackUserId | String? | Brand's Slack user ID |
brandPocName | String? | Brand point-of-contact name (from Copper) |
brandCcEmails | String[] | Additional CC email addresses for brand communications |
slackThreadTs | String? | Timestamp of the internal PS Slack logging thread for this deliverable |
brandNotifSlackTs | String? | Timestamp of the most recent brand-facing Slack notification |
creatorNotifSlackTs | String? | Timestamp of the most recent creator-facing Slack notification |
notified | Boolean | Whether the initial talking points notification has been sent |
batchId | String? | UUID shared by deliverables created in the same batch operation |
createdAt | DateTime | |
updatedAt | DateTime |
DeliverableStage (Enum)
The seven stages a deliverable can be in, in order:
| Stage | Who Acts | Description |
|---|---|---|
WAITING_ON_TALKING_POINTS | Brand | Brand has not yet submitted their campaign brief |
WAITING_FOR_SCRIPT | Creator | Creator needs to submit their script |
WAITING_FOR_SCRIPT_APPROVAL | Brand | Brand is reviewing the submitted script |
WAITING_FOR_VIDEO_DRAFT | Creator | Creator needs to submit their video draft |
WAITING_FOR_VIDEO_DRAFT_APPROVAL | Brand | Brand is reviewing the video draft |
WAITING_FOR_TALENT_TO_POST | Creator | All approved — creator needs to post the video |
COMPLETE | — | Video is live; brand and creator have been notified |
Note: Organic Mention, LinkedIn, and Newsletter deliverables skip the video stages — they go from
WAITING_FOR_SCRIPT_APPROVALdirectly toWAITING_FOR_TALENT_TO_POSTon script approval.
Submission
One row per creator submission round. A deliverable can have multiple submissions if the brand requests revisions (round increments on each re-submission).
| Field | Type | Notes |
|---|---|---|
id | Int | Primary key |
deliverableId | Int | FK → Deliverable.id |
type | String | "script" or "video" |
link | String | The submitted Google Docs or video URL |
status | String | "unreviewed", "accepted", or "declined" |
additionalNotes | String? | Brand's notes when accepting with conditions or declining |
round | Int | Submission round number, starting at 1. Increments on each re-submission. |
youtubeUrl | String? | Resolved YouTube URL after a direct upload completes in the background |
createdAt | DateTime | |
updatedAt | DateTime |
VideoComment
Timestamped comments left by the brand while reviewing a video draft. Stored per submission.
| Field | Type | Notes |
|---|---|---|
id | Int | Primary key |
submissionId | Int | FK → Submission.id. Deletes cascade when submission is deleted. |
timestamp | Float | Video timestamp in seconds where the comment applies |
text | String | Comment text |
createdAt | DateTime |
A brand that has left any video comments is blocked from approving the video until comments are cleared — they must request revisions and consolidate feedback instead.
AccessToken
Secure, multi-use form access tokens. Generated for creators and brands so they can access their form without a login.
| Field | Type | Notes |
|---|---|---|
id | Int | Primary key |
token | String | Unique token string embedded in the form URL. Unique index. |
entityType | String | "creator" or "brand" — determines which deliverables are shown |
entityName | String | The creator or brand name. Used to filter deliverables. |
testMode | Boolean | If true, only shows deliverables with [testing] in the name |
expiresAt | DateTime | Token expiry (30 days from creation) |
createdAt | DateTime | |
lastUsedAt | DateTime? | Last time the token was used (updated on each form load) |
Auth Tables
These tables are managed by BetterAuth and handle PS admin login.
user
PS admin accounts. Used to authenticate the admin panel.
| Field | Type | Notes |
|---|---|---|
id | String | Primary key |
name | String | Display name |
email | String | Login email |
emailVerified | Boolean | Email verification status |
image | String? | Profile photo URL |
createdAt | DateTime | |
updatedAt | DateTime |
session
Active authenticated sessions for PS admin users.
| Field | Type | Notes |
|---|---|---|
id | String | Primary key |
userId | String | FK → user.id |
token | String | Session token (unique) |
expiresAt | DateTime | Session expiry |
ipAddress | String? | IP at sign-in time |
userAgent | String? | Browser user agent |
createdAt | DateTime | |
updatedAt | DateTime |
account
OAuth provider account links associated with a user.
| Field | Type | Notes |
|---|---|---|
id | String | Primary key |
accountId | String | Provider account ID |
providerId | String | OAuth provider (e.g. "google") |
userId | String | FK → user.id |
accessToken | String? | OAuth access token |
refreshToken | String? | OAuth refresh token |
expiresAt | DateTime? | Access token expiry |
createdAt | DateTime | |
updatedAt | DateTime |
verification
Short-lived tokens for email verification / magic link flows.
| Field | Type | Notes |
|---|---|---|
id | String | Primary key |
identifier | String | Email address being verified |
value | String | One-time token in the magic link |
expiresAt | DateTime | Short expiry window |
createdAt | DateTime? | |
updatedAt | DateTime? |