mirror of
https://github.com/Dvorinka/Productier.git
synced 2026-06-04 04:23:00 +00:00
first commit
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
|
||||
PrepareContext(context.Context, string) (*sql.Stmt, error)
|
||||
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
|
||||
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ActivityEntry struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Title string
|
||||
Detail string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type BoardGroup struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Name string
|
||||
Color string
|
||||
SortOrder int32
|
||||
}
|
||||
|
||||
type CalendarEvent struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Title string
|
||||
Description string
|
||||
StartsAt time.Time
|
||||
EndsAt time.Time
|
||||
Color string
|
||||
LinkedTaskID sql.NullString
|
||||
Attachments json.RawMessage
|
||||
}
|
||||
|
||||
type FocusSession struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
TaskID sql.NullString
|
||||
Mode string
|
||||
StartedAt time.Time
|
||||
CompletedAt sql.NullTime
|
||||
PausedAt sql.NullTime
|
||||
PausedTotalSeconds int32
|
||||
DurationSeconds int32
|
||||
}
|
||||
|
||||
type Invite struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Email string
|
||||
Role string
|
||||
Token string
|
||||
CreatedAt time.Time
|
||||
Status string
|
||||
}
|
||||
|
||||
type Label struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Name string
|
||||
Color string
|
||||
}
|
||||
|
||||
type MailMessage struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
MailboxID string
|
||||
RemoteUid int64
|
||||
MessageID string
|
||||
Folder string
|
||||
FromAddress json.RawMessage
|
||||
ToRecipients json.RawMessage
|
||||
CcRecipients json.RawMessage
|
||||
Subject string
|
||||
Snippet string
|
||||
TextBody string
|
||||
HtmlBody string
|
||||
ReceivedAt time.Time
|
||||
IsRead bool
|
||||
LinkedTaskID sql.NullString
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type Mailbox struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Label string
|
||||
Email string
|
||||
DisplayName string
|
||||
ImapHost string
|
||||
ImapPort int32
|
||||
ImapUsername string
|
||||
ImapPasswordCiphertext string
|
||||
ImapUseTls bool
|
||||
SmtpHost string
|
||||
SmtpPort int32
|
||||
SmtpUsername string
|
||||
SmtpPasswordCiphertext string
|
||||
SmtpUseTls bool
|
||||
SyncStatus string
|
||||
SyncError string
|
||||
LastSyncedAt sql.NullTime
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type Member struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Name string
|
||||
Email string
|
||||
Role string
|
||||
Status string
|
||||
}
|
||||
|
||||
type Note struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
Title string
|
||||
Content string
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type OutgoingMail struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
MailboxID string
|
||||
ToRecipients json.RawMessage
|
||||
CcRecipients json.RawMessage
|
||||
BccRecipients json.RawMessage
|
||||
Subject string
|
||||
TextBody string
|
||||
HtmlBody string
|
||||
Status string
|
||||
ScheduledFor sql.NullTime
|
||||
SentAt sql.NullTime
|
||||
ErrorMessage string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
ID string
|
||||
WorkspaceSlug string
|
||||
BoardGroupID string
|
||||
Title string
|
||||
Description string
|
||||
Status string
|
||||
Color string
|
||||
DueAt sql.NullTime
|
||||
ScheduledStart sql.NullTime
|
||||
ScheduledEnd sql.NullTime
|
||||
AssigneeID sql.NullString
|
||||
LabelIds json.RawMessage
|
||||
Attachments json.RawMessage
|
||||
Comments json.RawMessage
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type Workspace struct {
|
||||
ID string
|
||||
Slug string
|
||||
Name string
|
||||
Role string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS workspaces (
|
||||
id text PRIMARY KEY,
|
||||
slug text NOT NULL UNIQUE,
|
||||
name text NOT NULL,
|
||||
role text NOT NULL,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS members (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
email text NOT NULL,
|
||||
role text NOT NULL,
|
||||
status text NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS members_workspace_email_idx ON members (workspace_slug, email);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS invites (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
email text NOT NULL,
|
||||
role text NOT NULL,
|
||||
token text NOT NULL UNIQUE,
|
||||
created_at timestamptz NOT NULL,
|
||||
status text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activity_entries (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
detail text NOT NULL,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS activity_entries_workspace_created_idx ON activity_entries (workspace_slug, created_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS board_groups (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
color text NOT NULL,
|
||||
sort_order integer NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS labels (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
color text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tasks (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
board_group_id text NOT NULL REFERENCES board_groups(id) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
status text NOT NULL,
|
||||
color text NOT NULL,
|
||||
due_at timestamptz,
|
||||
scheduled_start timestamptz,
|
||||
scheduled_end timestamptz,
|
||||
assignee_id text,
|
||||
label_ids jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
attachments jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
comments jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS tasks_workspace_updated_idx ON tasks (workspace_slug, updated_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS calendar_events (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
starts_at timestamptz NOT NULL,
|
||||
ends_at timestamptz NOT NULL,
|
||||
color text NOT NULL,
|
||||
linked_task_id text,
|
||||
attachments jsonb NOT NULL DEFAULT '[]'::jsonb
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS calendar_events_workspace_starts_idx ON calendar_events (workspace_slug, starts_at ASC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS notes (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
title text NOT NULL,
|
||||
content text NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS focus_sessions (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
task_id text,
|
||||
mode text NOT NULL,
|
||||
started_at timestamptz NOT NULL,
|
||||
completed_at timestamptz,
|
||||
paused_at timestamptz,
|
||||
paused_total_seconds integer NOT NULL DEFAULT 0,
|
||||
duration_seconds integer NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS focus_sessions_workspace_started_idx ON focus_sessions (workspace_slug, started_at DESC);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS focus_sessions;
|
||||
DROP TABLE IF EXISTS notes;
|
||||
DROP TABLE IF EXISTS calendar_events;
|
||||
DROP TABLE IF EXISTS tasks;
|
||||
DROP TABLE IF EXISTS labels;
|
||||
DROP TABLE IF EXISTS board_groups;
|
||||
DROP TABLE IF EXISTS activity_entries;
|
||||
DROP TABLE IF EXISTS invites;
|
||||
DROP INDEX IF EXISTS members_workspace_email_idx;
|
||||
DROP TABLE IF EXISTS members;
|
||||
DROP TABLE IF EXISTS workspaces;
|
||||
@@ -0,0 +1,75 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS mailboxes (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
label text NOT NULL,
|
||||
email text NOT NULL,
|
||||
display_name text NOT NULL DEFAULT '',
|
||||
imap_host text NOT NULL,
|
||||
imap_port integer NOT NULL,
|
||||
imap_username text NOT NULL,
|
||||
imap_password_ciphertext text NOT NULL,
|
||||
imap_use_tls boolean NOT NULL DEFAULT true,
|
||||
smtp_host text NOT NULL,
|
||||
smtp_port integer NOT NULL,
|
||||
smtp_username text NOT NULL,
|
||||
smtp_password_ciphertext text NOT NULL,
|
||||
smtp_use_tls boolean NOT NULL DEFAULT true,
|
||||
sync_status text NOT NULL DEFAULT 'idle',
|
||||
sync_error text NOT NULL DEFAULT '',
|
||||
last_synced_at timestamptz,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS mailboxes_workspace_updated_idx ON mailboxes (workspace_slug, updated_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS mail_messages (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
mailbox_id text NOT NULL REFERENCES mailboxes(id) ON DELETE CASCADE,
|
||||
remote_uid bigint NOT NULL,
|
||||
message_id text NOT NULL DEFAULT '',
|
||||
folder text NOT NULL DEFAULT 'INBOX',
|
||||
from_address jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
to_recipients jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
cc_recipients jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
subject text NOT NULL DEFAULT '',
|
||||
snippet text NOT NULL DEFAULT '',
|
||||
text_body text NOT NULL DEFAULT '',
|
||||
html_body text NOT NULL DEFAULT '',
|
||||
received_at timestamptz NOT NULL,
|
||||
is_read boolean NOT NULL DEFAULT false,
|
||||
linked_task_id text,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS mail_messages_mailbox_folder_uid_idx ON mail_messages (mailbox_id, folder, remote_uid);
|
||||
CREATE INDEX IF NOT EXISTS mail_messages_workspace_received_idx ON mail_messages (workspace_slug, received_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS outgoing_mails (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
mailbox_id text NOT NULL REFERENCES mailboxes(id) ON DELETE CASCADE,
|
||||
to_recipients jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
cc_recipients jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
bcc_recipients jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
subject text NOT NULL DEFAULT '',
|
||||
text_body text NOT NULL DEFAULT '',
|
||||
html_body text NOT NULL DEFAULT '',
|
||||
status text NOT NULL,
|
||||
scheduled_for timestamptz,
|
||||
sent_at timestamptz,
|
||||
error_message text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS outgoing_mails_workspace_created_idx ON outgoing_mails (workspace_slug, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS outgoing_mails_status_schedule_idx ON outgoing_mails (status, scheduled_for ASC);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS outgoing_mails;
|
||||
DROP TABLE IF EXISTS mail_messages;
|
||||
DROP TABLE IF EXISTS mailboxes;
|
||||
@@ -0,0 +1,79 @@
|
||||
-- +goose Up
|
||||
-- Contacts
|
||||
CREATE TABLE IF NOT EXISTS contacts (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
first_name text NOT NULL DEFAULT '',
|
||||
last_name text NOT NULL DEFAULT '',
|
||||
email text NOT NULL DEFAULT '',
|
||||
phone text NOT NULL DEFAULT '',
|
||||
company_id text,
|
||||
title text NOT NULL DEFAULT '',
|
||||
notes text NOT NULL DEFAULT '',
|
||||
avatar_url text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS contacts_workspace_updated_idx ON contacts (workspace_slug, updated_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS contacts_workspace_email_idx ON contacts (workspace_slug, email);
|
||||
|
||||
-- Companies
|
||||
CREATE TABLE IF NOT EXISTS companies (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
domain text NOT NULL DEFAULT '',
|
||||
website text NOT NULL DEFAULT '',
|
||||
industry text NOT NULL DEFAULT '',
|
||||
size text NOT NULL DEFAULT '',
|
||||
notes text NOT NULL DEFAULT '',
|
||||
logo_url text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS companies_workspace_updated_idx ON companies (workspace_slug, updated_at DESC);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS companies_workspace_name_idx ON companies (workspace_slug, name);
|
||||
|
||||
-- Add company foreign key to contacts
|
||||
ALTER TABLE contacts ADD CONSTRAINT contacts_company_fk FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL;
|
||||
|
||||
-- Contact-Task links
|
||||
CREATE TABLE IF NOT EXISTS contact_tasks (
|
||||
id text PRIMARY KEY,
|
||||
contact_id text NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
task_id text NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS contact_tasks_unique_idx ON contact_tasks (contact_id, task_id);
|
||||
|
||||
-- Contact-Event links
|
||||
CREATE TABLE IF NOT EXISTS contact_events (
|
||||
id text PRIMARY KEY,
|
||||
contact_id text NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
event_id text NOT NULL REFERENCES calendar_events(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS contact_events_unique_idx ON contact_events (contact_id, event_id);
|
||||
|
||||
-- Contact-Email links (track which contacts are involved in emails)
|
||||
CREATE TABLE IF NOT EXISTS contact_emails (
|
||||
id text PRIMARY KEY,
|
||||
contact_id text NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
mail_message_id text NOT NULL REFERENCES mail_messages(id) ON DELETE CASCADE,
|
||||
role text NOT NULL DEFAULT 'recipient', -- sender, recipient, cc
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS contact_emails_unique_idx ON contact_emails (contact_id, mail_message_id);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS contact_emails;
|
||||
DROP TABLE IF EXISTS contact_events;
|
||||
DROP TABLE IF EXISTS contact_tasks;
|
||||
ALTER TABLE contacts DROP CONSTRAINT IF EXISTS contacts_company_fk;
|
||||
DROP TABLE IF EXISTS contacts;
|
||||
DROP TABLE IF EXISTS companies;
|
||||
@@ -0,0 +1,71 @@
|
||||
-- +goose Up
|
||||
-- Recurring tasks
|
||||
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS recurrence_rule text NOT NULL DEFAULT '';
|
||||
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS recurrence_end timestamptz;
|
||||
|
||||
-- Recurring events
|
||||
ALTER TABLE calendar_events ADD COLUMN IF NOT EXISTS recurrence_rule text NOT NULL DEFAULT '';
|
||||
ALTER TABLE calendar_events ADD COLUMN IF NOT EXISTS recurrence_end timestamptz;
|
||||
|
||||
-- Quick capture inbox
|
||||
CREATE TABLE IF NOT EXISTS inbox_items (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
content text NOT NULL,
|
||||
source text NOT NULL DEFAULT 'manual', -- manual, email, api
|
||||
processed boolean NOT NULL DEFAULT false,
|
||||
processed_at timestamptz,
|
||||
processed_entity_type text, -- task, note, event
|
||||
processed_entity_id text,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS inbox_items_workspace_created_idx ON inbox_items (workspace_slug, created_at DESC);
|
||||
|
||||
-- Time tracking
|
||||
CREATE TABLE IF NOT EXISTS time_entries (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
task_id text REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
description text NOT NULL DEFAULT '',
|
||||
started_at timestamptz NOT NULL,
|
||||
ended_at timestamptz,
|
||||
duration_seconds integer NOT NULL DEFAULT 0,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS time_entries_workspace_started_idx ON time_entries (workspace_slug, started_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS time_entries_task_idx ON time_entries (task_id);
|
||||
|
||||
-- Saved filters/views
|
||||
CREATE TABLE IF NOT EXISTS saved_views (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
entity_type text NOT NULL, -- tasks, contacts, companies
|
||||
filter_json jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
sort_json jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
is_default boolean NOT NULL DEFAULT false,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS saved_views_workspace_type_idx ON saved_views (workspace_slug, entity_type);
|
||||
|
||||
-- Archive support
|
||||
ALTER TABLE tasks ADD COLUMN IF NOT EXISTS archived boolean NOT NULL DEFAULT false;
|
||||
ALTER TABLE calendar_events ADD COLUMN IF NOT EXISTS archived boolean NOT NULL DEFAULT false;
|
||||
ALTER TABLE notes ADD COLUMN IF NOT EXISTS archived boolean NOT NULL DEFAULT false;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE tasks DROP COLUMN IF EXISTS recurrence_rule;
|
||||
ALTER TABLE tasks DROP COLUMN IF EXISTS recurrence_end;
|
||||
ALTER TABLE calendar_events DROP COLUMN IF EXISTS recurrence_rule;
|
||||
ALTER TABLE calendar_events DROP COLUMN IF EXISTS recurrence_end;
|
||||
DROP TABLE IF EXISTS inbox_items;
|
||||
DROP TABLE IF EXISTS time_entries;
|
||||
DROP TABLE IF EXISTS saved_views;
|
||||
ALTER TABLE tasks DROP COLUMN IF EXISTS archived;
|
||||
ALTER TABLE calendar_events DROP COLUMN IF EXISTS archived;
|
||||
ALTER TABLE notes DROP COLUMN IF EXISTS archived;
|
||||
@@ -0,0 +1,70 @@
|
||||
-- +goose Up
|
||||
-- Integrations table for external service connections
|
||||
CREATE TABLE IF NOT EXISTS integrations (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
provider text NOT NULL, -- google_calendar, slack, etc.
|
||||
name text NOT NULL,
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
credentials_ciphertext text NOT NULL,
|
||||
status text NOT NULL DEFAULT 'active',
|
||||
last_sync_at timestamptz,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS integrations_workspace_provider_idx ON integrations (workspace_slug, provider);
|
||||
|
||||
-- Webhooks for external notifications
|
||||
CREATE TABLE IF NOT EXISTS webhooks (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
url text NOT NULL,
|
||||
secret text NOT NULL,
|
||||
events jsonb NOT NULL DEFAULT '[]'::jsonb, -- ["task.created", "task.completed", etc.]
|
||||
active boolean NOT NULL DEFAULT true,
|
||||
last_triggered_at timestamptz,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS webhooks_workspace_idx ON webhooks (workspace_slug);
|
||||
|
||||
-- Notifications for users
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
user_email text NOT NULL,
|
||||
type text NOT NULL, -- task_assigned, mention, comment, etc.
|
||||
title text NOT NULL,
|
||||
body text NOT NULL DEFAULT '',
|
||||
entity_type text, -- task, event, note
|
||||
entity_id text,
|
||||
read boolean NOT NULL DEFAULT false,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS notifications_user_created_idx ON notifications (user_email, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS notifications_unread_idx ON notifications (user_email, read) WHERE read = false;
|
||||
|
||||
-- Presence tracking for real-time collaboration
|
||||
CREATE TABLE IF NOT EXISTS presence (
|
||||
id text PRIMARY KEY,
|
||||
workspace_slug text NOT NULL REFERENCES workspaces(slug) ON DELETE CASCADE,
|
||||
user_email text NOT NULL,
|
||||
user_name text NOT NULL,
|
||||
entity_type text, -- board, task, note, etc.
|
||||
entity_id text,
|
||||
last_seen_at timestamptz NOT NULL,
|
||||
created_at timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS presence_workspace_entity_idx ON presence (workspace_slug, entity_type, entity_id);
|
||||
CREATE INDEX IF NOT EXISTS presence_user_idx ON presence (user_email);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS presence;
|
||||
DROP TABLE IF EXISTS notifications;
|
||||
DROP TABLE IF EXISTS webhooks;
|
||||
DROP TABLE IF EXISTS integrations;
|
||||
@@ -0,0 +1,217 @@
|
||||
-- name: CountWorkspaces :one
|
||||
SELECT COUNT(*) FROM workspaces;
|
||||
|
||||
-- name: ListWorkspaces :many
|
||||
SELECT id, slug, name, role, created_at
|
||||
FROM workspaces
|
||||
ORDER BY created_at ASC;
|
||||
|
||||
-- name: CreateWorkspace :exec
|
||||
INSERT INTO workspaces (id, slug, name, role, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5);
|
||||
|
||||
-- name: ListMembers :many
|
||||
SELECT id, workspace_slug, name, email, role, status
|
||||
FROM members
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY name ASC;
|
||||
|
||||
-- name: CreateMember :exec
|
||||
INSERT INTO members (id, workspace_slug, name, email, role, status)
|
||||
VALUES ($1, $2, $3, $4, $5, $6);
|
||||
|
||||
-- name: GetMemberByWorkspaceAndEmail :one
|
||||
SELECT id, workspace_slug, name, email, role, status
|
||||
FROM members
|
||||
WHERE workspace_slug = $1 AND email = $2;
|
||||
|
||||
-- name: ListInvites :many
|
||||
SELECT id, workspace_slug, email, role, token, created_at, status
|
||||
FROM invites
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: GetInviteByToken :one
|
||||
SELECT id, workspace_slug, email, role, token, created_at, status
|
||||
FROM invites
|
||||
WHERE token = $1;
|
||||
|
||||
-- name: CreateInvite :one
|
||||
INSERT INTO invites (id, workspace_slug, email, role, token, created_at, status)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING id, workspace_slug, email, role, token, created_at, status;
|
||||
|
||||
-- name: AcceptInvite :one
|
||||
UPDATE invites
|
||||
SET status = 'accepted'
|
||||
WHERE token = $1
|
||||
RETURNING id, workspace_slug, email, role, token, created_at, status;
|
||||
|
||||
-- name: ListActivities :many
|
||||
SELECT id, workspace_slug, title, detail, created_at
|
||||
FROM activity_entries
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 40;
|
||||
|
||||
-- name: CreateActivity :exec
|
||||
INSERT INTO activity_entries (id, workspace_slug, title, detail, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5);
|
||||
|
||||
-- name: TrimActivities :exec
|
||||
DELETE FROM activity_entries
|
||||
WHERE id IN (
|
||||
SELECT id
|
||||
FROM activity_entries
|
||||
WHERE activity_entries.workspace_slug = $1
|
||||
ORDER BY created_at DESC
|
||||
OFFSET 40
|
||||
);
|
||||
|
||||
-- name: ListBoardGroups :many
|
||||
SELECT id, workspace_slug, name, color, sort_order
|
||||
FROM board_groups
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY sort_order ASC, name ASC;
|
||||
|
||||
-- name: GetBoardGroupByID :one
|
||||
SELECT id, workspace_slug, name, color, sort_order
|
||||
FROM board_groups
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: CreateBoardGroup :one
|
||||
INSERT INTO board_groups (id, workspace_slug, name, color, sort_order)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, workspace_slug, name, color, sort_order;
|
||||
|
||||
-- name: UpdateBoardGroup :one
|
||||
UPDATE board_groups
|
||||
SET name = $2,
|
||||
color = $3,
|
||||
sort_order = $4
|
||||
WHERE id = $1
|
||||
RETURNING id, workspace_slug, name, color, sort_order;
|
||||
|
||||
-- name: CountBoardGroupsByWorkspace :one
|
||||
SELECT COUNT(*) FROM board_groups WHERE workspace_slug = $1;
|
||||
|
||||
-- name: ListLabels :many
|
||||
SELECT id, workspace_slug, name, color
|
||||
FROM labels
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY name ASC;
|
||||
|
||||
-- name: CreateLabel :one
|
||||
INSERT INTO labels (id, workspace_slug, name, color)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, workspace_slug, name, color;
|
||||
|
||||
-- name: ListTasks :many
|
||||
SELECT id, workspace_slug, board_group_id, title, description, status, color, due_at, scheduled_start, scheduled_end, assignee_id, label_ids, attachments, comments, created_at, updated_at
|
||||
FROM tasks
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY updated_at DESC;
|
||||
|
||||
-- name: GetTaskByID :one
|
||||
SELECT id, workspace_slug, board_group_id, title, description, status, color, due_at, scheduled_start, scheduled_end, assignee_id, label_ids, attachments, comments, created_at, updated_at
|
||||
FROM tasks
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: CreateTask :one
|
||||
INSERT INTO tasks (id, workspace_slug, board_group_id, title, description, status, color, due_at, scheduled_start, scheduled_end, assignee_id, label_ids, attachments, comments, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING id, workspace_slug, board_group_id, title, description, status, color, due_at, scheduled_start, scheduled_end, assignee_id, label_ids, attachments, comments, created_at, updated_at;
|
||||
|
||||
-- name: UpdateTask :one
|
||||
UPDATE tasks
|
||||
SET title = $2,
|
||||
description = $3,
|
||||
status = $4,
|
||||
board_group_id = $5,
|
||||
color = $6,
|
||||
due_at = $7,
|
||||
scheduled_start = $8,
|
||||
scheduled_end = $9,
|
||||
assignee_id = $10,
|
||||
label_ids = $11,
|
||||
attachments = $12,
|
||||
comments = $13,
|
||||
updated_at = $14
|
||||
WHERE id = $1
|
||||
RETURNING id, workspace_slug, board_group_id, title, description, status, color, due_at, scheduled_start, scheduled_end, assignee_id, label_ids, attachments, comments, created_at, updated_at;
|
||||
|
||||
-- name: ListCalendarEvents :many
|
||||
SELECT id, workspace_slug, title, description, starts_at, ends_at, color, linked_task_id, attachments
|
||||
FROM calendar_events
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY starts_at ASC;
|
||||
|
||||
-- name: GetCalendarEventByID :one
|
||||
SELECT id, workspace_slug, title, description, starts_at, ends_at, color, linked_task_id, attachments
|
||||
FROM calendar_events
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: CreateCalendarEvent :one
|
||||
INSERT INTO calendar_events (id, workspace_slug, title, description, starts_at, ends_at, color, linked_task_id, attachments)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
RETURNING id, workspace_slug, title, description, starts_at, ends_at, color, linked_task_id, attachments;
|
||||
|
||||
-- name: UpdateCalendarEvent :one
|
||||
UPDATE calendar_events
|
||||
SET title = $2,
|
||||
description = $3,
|
||||
starts_at = $4,
|
||||
ends_at = $5,
|
||||
color = $6,
|
||||
linked_task_id = $7,
|
||||
attachments = $8
|
||||
WHERE id = $1
|
||||
RETURNING id, workspace_slug, title, description, starts_at, ends_at, color, linked_task_id, attachments;
|
||||
|
||||
-- name: ListNotes :many
|
||||
SELECT id, workspace_slug, title, content, updated_at
|
||||
FROM notes
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY updated_at DESC;
|
||||
|
||||
-- name: GetNoteByID :one
|
||||
SELECT id, workspace_slug, title, content, updated_at
|
||||
FROM notes
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: CreateNote :one
|
||||
INSERT INTO notes (id, workspace_slug, title, content, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, workspace_slug, title, content, updated_at;
|
||||
|
||||
-- name: UpdateNote :one
|
||||
UPDATE notes
|
||||
SET title = $2,
|
||||
content = $3,
|
||||
updated_at = $4
|
||||
WHERE id = $1
|
||||
RETURNING id, workspace_slug, title, content, updated_at;
|
||||
|
||||
-- name: ListFocusSessions :many
|
||||
SELECT id, workspace_slug, task_id, mode, started_at, completed_at, paused_at, paused_total_seconds, duration_seconds
|
||||
FROM focus_sessions
|
||||
WHERE workspace_slug = $1
|
||||
ORDER BY started_at DESC;
|
||||
|
||||
-- name: GetFocusSessionByID :one
|
||||
SELECT id, workspace_slug, task_id, mode, started_at, completed_at, paused_at, paused_total_seconds, duration_seconds
|
||||
FROM focus_sessions
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: CreateFocusSession :one
|
||||
INSERT INTO focus_sessions (id, workspace_slug, task_id, mode, started_at, completed_at, paused_at, paused_total_seconds, duration_seconds)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
RETURNING id, workspace_slug, task_id, mode, started_at, completed_at, paused_at, paused_total_seconds, duration_seconds;
|
||||
|
||||
-- name: UpdateFocusSession :one
|
||||
UPDATE focus_sessions
|
||||
SET completed_at = $2,
|
||||
paused_at = $3,
|
||||
paused_total_seconds = $4
|
||||
WHERE id = $1
|
||||
RETURNING id, workspace_slug, task_id, mode, started_at, completed_at, paused_at, paused_total_seconds, duration_seconds;
|
||||
Reference in New Issue
Block a user