@topogram/template-todo 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -0
- package/implementation/README.md +9 -0
- package/implementation/backend/reference.js +206 -0
- package/implementation/backend/repository-reference.js +74 -0
- package/implementation/backend/repository-renderers.js +442 -0
- package/implementation/index.js +53 -0
- package/implementation/runtime/check-renderers.js +215 -0
- package/implementation/runtime/checks.js +120 -0
- package/implementation/runtime/reference.js +92 -0
- package/implementation/web/reference.js +51 -0
- package/implementation/web/renderers.js +1223 -0
- package/implementation/web/screens-reference.js +15 -0
- package/package.json +31 -0
- package/topogram/actors/actor-user.tg +6 -0
- package/topogram/capabilities/cap-complete-task.tg +12 -0
- package/topogram/capabilities/cap-create-project.tg +11 -0
- package/topogram/capabilities/cap-create-task.tg +14 -0
- package/topogram/capabilities/cap-create-user.tg +11 -0
- package/topogram/capabilities/cap-delete-task.tg +12 -0
- package/topogram/capabilities/cap-download-task-export.tg +10 -0
- package/topogram/capabilities/cap-export-tasks.tg +11 -0
- package/topogram/capabilities/cap-get-project.tg +11 -0
- package/topogram/capabilities/cap-get-task-export-job.tg +11 -0
- package/topogram/capabilities/cap-get-task.tg +11 -0
- package/topogram/capabilities/cap-get-user.tg +11 -0
- package/topogram/capabilities/cap-list-projects.tg +11 -0
- package/topogram/capabilities/cap-list-tasks.tg +11 -0
- package/topogram/capabilities/cap-list-users.tg +11 -0
- package/topogram/capabilities/cap-update-project.tg +12 -0
- package/topogram/capabilities/cap-update-task.tg +12 -0
- package/topogram/capabilities/cap-update-user.tg +12 -0
- package/topogram/components/component-ui-task-board.tg +33 -0
- package/topogram/components/component-ui-task-calendar.tg +30 -0
- package/topogram/components/component-ui-task-summary.tg +23 -0
- package/topogram/components/component-ui-task-table.tg +34 -0
- package/topogram/decisions/decision-task-ownership.tg +9 -0
- package/topogram/docs/glossary/user.md +22 -0
- package/topogram/docs/journeys/task-creation-and-ownership.md +57 -0
- package/topogram/entities/entity-project.tg +28 -0
- package/topogram/entities/entity-task.tg +38 -0
- package/topogram/entities/entity-user.tg +24 -0
- package/topogram/enums/enum-export-job-status.tg +3 -0
- package/topogram/enums/enum-project-status.tg +3 -0
- package/topogram/enums/enum-task-priority.tg +3 -0
- package/topogram/enums/enum-task-status.tg +3 -0
- package/topogram/operations/operation-task-creation-monitoring.tg +10 -0
- package/topogram/projections/proj-api.tg +177 -0
- package/topogram/projections/proj-db-postgres.tg +55 -0
- package/topogram/projections/proj-db-sqlite.tg +47 -0
- package/topogram/projections/proj-ui-shared.tg +133 -0
- package/topogram/projections/proj-ui-web-react.tg +92 -0
- package/topogram/projections/proj-ui-web.tg +92 -0
- package/topogram/rules/rule-no-task-creation-in-archived-project.tg +10 -0
- package/topogram/rules/rule-only-active-users-may-own-tasks.tg +10 -0
- package/topogram/shapes/shape-input-complete-task.tg +11 -0
- package/topogram/shapes/shape-input-create-project.tg +6 -0
- package/topogram/shapes/shape-input-create-task.tg +6 -0
- package/topogram/shapes/shape-input-create-user.tg +6 -0
- package/topogram/shapes/shape-input-delete-task.tg +10 -0
- package/topogram/shapes/shape-input-export-tasks.tg +13 -0
- package/topogram/shapes/shape-input-get-project.tg +10 -0
- package/topogram/shapes/shape-input-get-task-export-job.tg +10 -0
- package/topogram/shapes/shape-input-get-task.tg +10 -0
- package/topogram/shapes/shape-input-get-user.tg +10 -0
- package/topogram/shapes/shape-input-list-projects.tg +11 -0
- package/topogram/shapes/shape-input-list-tasks.tg +14 -0
- package/topogram/shapes/shape-input-list-users.tg +11 -0
- package/topogram/shapes/shape-input-update-project.tg +14 -0
- package/topogram/shapes/shape-input-update-task.tg +16 -0
- package/topogram/shapes/shape-input-update-user.tg +13 -0
- package/topogram/shapes/shape-output-project-card.tg +6 -0
- package/topogram/shapes/shape-output-project-detail.tg +6 -0
- package/topogram/shapes/shape-output-task-card.tg +19 -0
- package/topogram/shapes/shape-output-task-detail.tg +6 -0
- package/topogram/shapes/shape-output-task-export-callback.tg +14 -0
- package/topogram/shapes/shape-output-task-export-job.tg +13 -0
- package/topogram/shapes/shape-output-task-export-status.tg +17 -0
- package/topogram/shapes/shape-output-user-card.tg +6 -0
- package/topogram/shapes/shape-output-user-detail.tg +6 -0
- package/topogram/terms/term-user.tg +5 -0
- package/topogram/verifications/verification-create-task-policy.tg +15 -0
- package/topogram/verifications/verification-runtime-smoke.tg +16 -0
- package/topogram/verifications/verification-task-runtime-flow.tg +31 -0
- package/topogram-template.json +11 -0
- package/topogram.project.json +53 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const TODO_WEB_SCREEN_REFERENCE = {
|
|
2
|
+
projectListScreenId: "project_list",
|
|
3
|
+
projectDetailScreenId: "project_detail",
|
|
4
|
+
projectCreateScreenId: "project_create",
|
|
5
|
+
projectEditScreenId: "project_edit",
|
|
6
|
+
userListScreenId: "user_list",
|
|
7
|
+
userDetailScreenId: "user_detail",
|
|
8
|
+
userCreateScreenId: "user_create",
|
|
9
|
+
userEditScreenId: "user_edit",
|
|
10
|
+
listScreenId: "task_list",
|
|
11
|
+
detailScreenId: "task_detail",
|
|
12
|
+
createScreenId: "task_create",
|
|
13
|
+
editScreenId: "task_edit",
|
|
14
|
+
exportsScreenId: "task_exports"
|
|
15
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@topogram/template-todo",
|
|
3
|
+
"version": "0.1.30",
|
|
4
|
+
"description": "Topogram template pack for starting a generated Todo app.",
|
|
5
|
+
"private": false,
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"topogram-template.json",
|
|
10
|
+
"topogram",
|
|
11
|
+
"topogram.project.json",
|
|
12
|
+
"implementation",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"registry": "https://registry.npmjs.org",
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"catalog:update": "node ./scripts/update-catalog-version.mjs",
|
|
21
|
+
"pack:check": "bash ./scripts/verify-template-package.sh",
|
|
22
|
+
"release:prepare": "bash ./scripts/prepare-release.sh",
|
|
23
|
+
"release:check": "bash ./scripts/check-release-version.sh"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@topogram/cli": "0.3.34",
|
|
27
|
+
"@topogram/generator-hono-api": "0.2.6",
|
|
28
|
+
"@topogram/generator-postgres-db": "0.1.6",
|
|
29
|
+
"@topogram/generator-sveltekit-web": "0.1.14"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
capability cap_complete_task {
|
|
2
|
+
name "Complete Task"
|
|
3
|
+
description "Allows a user to mark a task complete"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_task]
|
|
7
|
+
updates [entity_task]
|
|
8
|
+
input [shape_input_complete_task]
|
|
9
|
+
output [shape_output_task_detail]
|
|
10
|
+
|
|
11
|
+
status active
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability cap_create_project {
|
|
2
|
+
name "Create Project"
|
|
3
|
+
description "Allows a user to create a new project"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
creates [entity_project]
|
|
7
|
+
input [shape_input_create_project]
|
|
8
|
+
output [shape_output_project_detail]
|
|
9
|
+
|
|
10
|
+
status active
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
capability cap_create_task {
|
|
2
|
+
name "Create Task"
|
|
3
|
+
description "Allows a user to create a new task"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
|
|
7
|
+
creates [entity_task]
|
|
8
|
+
reads [entity_project, entity_user]
|
|
9
|
+
|
|
10
|
+
input [shape_input_create_task]
|
|
11
|
+
output [shape_output_task_detail]
|
|
12
|
+
|
|
13
|
+
status active
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
capability cap_delete_task {
|
|
2
|
+
name "Delete Task"
|
|
3
|
+
description "Allows a user to archive a task through the delete endpoint"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_task]
|
|
7
|
+
deletes [entity_task]
|
|
8
|
+
input [shape_input_delete_task]
|
|
9
|
+
output [shape_output_task_detail]
|
|
10
|
+
|
|
11
|
+
status active
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability cap_export_tasks {
|
|
2
|
+
name "Export Tasks"
|
|
3
|
+
description "Starts an asynchronous export job for tasks"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_task, entity_project, entity_user]
|
|
7
|
+
input [shape_input_export_tasks]
|
|
8
|
+
output [shape_output_task_export_job]
|
|
9
|
+
|
|
10
|
+
status active
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability cap_get_task_export_job {
|
|
2
|
+
name "Get Task Export Job"
|
|
3
|
+
description "Fetches the current status of a task export job"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_task]
|
|
7
|
+
input [shape_input_get_task_export_job]
|
|
8
|
+
output [shape_output_task_export_status]
|
|
9
|
+
|
|
10
|
+
status active
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
capability cap_list_tasks {
|
|
2
|
+
name "List Tasks"
|
|
3
|
+
description "Allows a user to list tasks"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_task, entity_project, entity_user]
|
|
7
|
+
input [shape_input_list_tasks]
|
|
8
|
+
output [shape_output_task_detail]
|
|
9
|
+
|
|
10
|
+
status active
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
capability cap_update_project {
|
|
2
|
+
name "Update Project"
|
|
3
|
+
description "Allows a user to update mutable project fields"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_project]
|
|
7
|
+
updates [entity_project]
|
|
8
|
+
input [shape_input_update_project]
|
|
9
|
+
output [shape_output_project_detail]
|
|
10
|
+
|
|
11
|
+
status active
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
capability cap_update_task {
|
|
2
|
+
name "Update Task"
|
|
3
|
+
description "Allows a user to update mutable task fields"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_task]
|
|
7
|
+
updates [entity_task]
|
|
8
|
+
input [shape_input_update_task]
|
|
9
|
+
output [shape_output_task_detail]
|
|
10
|
+
|
|
11
|
+
status active
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
capability cap_update_user {
|
|
2
|
+
name "Update User"
|
|
3
|
+
description "Allows a user to update mutable user fields"
|
|
4
|
+
|
|
5
|
+
actors [actor_user]
|
|
6
|
+
reads [entity_user]
|
|
7
|
+
updates [entity_user]
|
|
8
|
+
input [shape_input_update_user]
|
|
9
|
+
output [shape_output_user_detail]
|
|
10
|
+
|
|
11
|
+
status active
|
|
12
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
component component_ui_task_board {
|
|
2
|
+
name "Task Board"
|
|
3
|
+
description "Reusable kanban-style task board grouped by status"
|
|
4
|
+
category collection
|
|
5
|
+
|
|
6
|
+
props {
|
|
7
|
+
columns array required
|
|
8
|
+
loading boolean optional default false
|
|
9
|
+
selected_id text optional default null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
events {
|
|
13
|
+
card_select shape_output_task_card
|
|
14
|
+
card_move shape_input_update_task
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
slots {
|
|
18
|
+
toolbar "Board actions"
|
|
19
|
+
empty_state "Empty board content"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
behavior [selection, grouping, drag_drop, optimistic_update]
|
|
23
|
+
behaviors {
|
|
24
|
+
selection mode single state selected_id emits card_select
|
|
25
|
+
grouping fields [status]
|
|
26
|
+
drag_drop axis horizontal reorder true
|
|
27
|
+
optimistic_update actions [cap_update_task] rollback true
|
|
28
|
+
}
|
|
29
|
+
patterns [board_view, resource_cards]
|
|
30
|
+
regions [results, toolbar]
|
|
31
|
+
version "1.0"
|
|
32
|
+
status active
|
|
33
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
component component_ui_task_calendar {
|
|
2
|
+
name "Task Calendar"
|
|
3
|
+
description "Reusable calendar view for scheduled tasks"
|
|
4
|
+
category collection
|
|
5
|
+
|
|
6
|
+
props {
|
|
7
|
+
events array required
|
|
8
|
+
loading boolean optional default false
|
|
9
|
+
selected_id text optional default null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
events {
|
|
13
|
+
event_select shape_output_task_card
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
slots {
|
|
17
|
+
toolbar "Calendar controls"
|
|
18
|
+
empty_state "Empty calendar content"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
behavior [selection, filtering]
|
|
22
|
+
behaviors {
|
|
23
|
+
selection mode single state selected_id emits event_select
|
|
24
|
+
filtering fields [status, ownerId]
|
|
25
|
+
}
|
|
26
|
+
patterns [calendar_view]
|
|
27
|
+
regions [results, toolbar]
|
|
28
|
+
version "1.0"
|
|
29
|
+
status active
|
|
30
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
component component_ui_task_summary {
|
|
2
|
+
name "Task Summary"
|
|
3
|
+
description "Reusable summary metrics for task workload state"
|
|
4
|
+
category display
|
|
5
|
+
|
|
6
|
+
props {
|
|
7
|
+
metrics object required
|
|
8
|
+
loading boolean optional default false
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
slots {
|
|
12
|
+
empty_state "Summary unavailable content"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
behavior [realtime_update]
|
|
16
|
+
behaviors {
|
|
17
|
+
realtime_update source cap_list_tasks merge replace
|
|
18
|
+
}
|
|
19
|
+
patterns [summary_stats]
|
|
20
|
+
regions [hero, summary]
|
|
21
|
+
version "1.0"
|
|
22
|
+
status active
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
component component_ui_task_table {
|
|
2
|
+
name "Task Table"
|
|
3
|
+
description "Reusable tabular task collection with selection, sorting, filtering, and export affordances"
|
|
4
|
+
category collection
|
|
5
|
+
|
|
6
|
+
props {
|
|
7
|
+
rows array required
|
|
8
|
+
selected_ids array optional default []
|
|
9
|
+
loading boolean optional default false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
events {
|
|
13
|
+
row_select shape_output_task_card
|
|
14
|
+
export_request shape_input_export_tasks
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
slots {
|
|
18
|
+
toolbar "Table actions and filters"
|
|
19
|
+
empty_state "Empty task list content"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
behavior [selection, sorting, filtering, pagination, bulk_action]
|
|
23
|
+
behaviors {
|
|
24
|
+
selection mode multi state selected_ids emits row_select
|
|
25
|
+
sorting fields [title, status, priority, dueAt, created_at] default [created_at, desc]
|
|
26
|
+
filtering fields [project_id, owner_id, status]
|
|
27
|
+
pagination mode cursor page_size 25
|
|
28
|
+
bulk_action actions [cap_export_tasks] state selected_ids emits export_request
|
|
29
|
+
}
|
|
30
|
+
patterns [resource_table, data_grid_view]
|
|
31
|
+
regions [results, toolbar]
|
|
32
|
+
version "1.0"
|
|
33
|
+
status active
|
|
34
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
decision dec_task_ownership {
|
|
2
|
+
name "Active task ownership is singular"
|
|
3
|
+
description "Active tasks use one accountable owner"
|
|
4
|
+
|
|
5
|
+
context [accountability, simplified_workflows, cleaner_ui]
|
|
6
|
+
consequences [easier_reporting, less_flexible_collaboration]
|
|
7
|
+
|
|
8
|
+
status accepted
|
|
9
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: user
|
|
3
|
+
kind: glossary
|
|
4
|
+
title: User
|
|
5
|
+
status: canonical
|
|
6
|
+
summary: Workspace member who can own projects and be assigned tasks.
|
|
7
|
+
aliases:
|
|
8
|
+
- owner
|
|
9
|
+
- assignee
|
|
10
|
+
related_entities:
|
|
11
|
+
- entity_user
|
|
12
|
+
related_capabilities:
|
|
13
|
+
- cap_create_user
|
|
14
|
+
- cap_update_user
|
|
15
|
+
tags:
|
|
16
|
+
- naming
|
|
17
|
+
- identity
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
A user is a workspace member who can be assigned tasks and may own projects.
|
|
21
|
+
|
|
22
|
+
Legacy product language sometimes says "owner" for both task assignment and project ownership, but the canonical Topogram term is `user`. The task and project models keep `owner_id` as the relationship field name because that reflects current product semantics, while the resource itself remains `entity_user`.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: task_creation_and_ownership
|
|
3
|
+
kind: journey
|
|
4
|
+
title: Task Creation And Ownership
|
|
5
|
+
status: canonical
|
|
6
|
+
summary: A user creates a task in an active project, assigns clear ownership, and can immediately find it again to keep work moving.
|
|
7
|
+
actors:
|
|
8
|
+
- user
|
|
9
|
+
related_actors:
|
|
10
|
+
- actor_user
|
|
11
|
+
success_outcome: The new task is captured in the right project with valid ownership and remains easy to review and update.
|
|
12
|
+
related_entities:
|
|
13
|
+
- entity_task
|
|
14
|
+
- entity_project
|
|
15
|
+
- entity_user
|
|
16
|
+
related_capabilities:
|
|
17
|
+
- cap_create_task
|
|
18
|
+
- cap_get_task
|
|
19
|
+
- cap_list_tasks
|
|
20
|
+
- cap_update_task
|
|
21
|
+
related_rules:
|
|
22
|
+
- rule_no_task_creation_in_archived_project
|
|
23
|
+
- rule_only_active_users_may_own_tasks
|
|
24
|
+
related_projections:
|
|
25
|
+
- proj_api
|
|
26
|
+
- proj_ui_shared
|
|
27
|
+
- proj_ui_web
|
|
28
|
+
failure_signals:
|
|
29
|
+
- The user can create a task in an archived project.
|
|
30
|
+
- The user can assign a task to an inactive owner.
|
|
31
|
+
- The newly created task is hard to find from the normal task list or detail flow.
|
|
32
|
+
tags:
|
|
33
|
+
- journey
|
|
34
|
+
- task-management
|
|
35
|
+
- ownership
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
This journey captures the most common Todo flow: turning a piece of work into a tracked task with clear ownership.
|
|
39
|
+
|
|
40
|
+
The user intent is not just to persist a row. The user needs confidence that the task belongs to the correct project, follows ownership rules, and shows up immediately in the standard list and detail views used to manage work.
|
|
41
|
+
|
|
42
|
+
## Happy Path
|
|
43
|
+
|
|
44
|
+
1. The user starts from an active project and opens the new-task flow.
|
|
45
|
+
2. The user enters the task details, including priority and an optional owner.
|
|
46
|
+
3. The system accepts the task only if the project can still receive new work and the owner is active.
|
|
47
|
+
4. The user can immediately find the new task in task list and task detail surfaces.
|
|
48
|
+
5. The user can keep the flow moving by updating the task as work progresses.
|
|
49
|
+
|
|
50
|
+
## Alternate Paths
|
|
51
|
+
|
|
52
|
+
- If the project has already been archived, task creation should stop before the new task is accepted.
|
|
53
|
+
- If the chosen owner is inactive, the flow should block invalid assignment instead of creating ambiguous accountability.
|
|
54
|
+
|
|
55
|
+
## Change Review Notes
|
|
56
|
+
|
|
57
|
+
Review this journey when changing task creation rules, ownership semantics, project archival behavior, task list visibility, or the create/update task UI flow.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
entity entity_project {
|
|
2
|
+
name "Project"
|
|
3
|
+
description "A grouping container for tasks"
|
|
4
|
+
|
|
5
|
+
fields {
|
|
6
|
+
id uuid required
|
|
7
|
+
name string required
|
|
8
|
+
description text optional
|
|
9
|
+
status project_status required default active
|
|
10
|
+
owner_id uuid optional
|
|
11
|
+
created_at datetime required
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
keys {
|
|
15
|
+
primary [id]
|
|
16
|
+
unique [name]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
relations {
|
|
20
|
+
owner_id references entity_user.id
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
invariants {
|
|
24
|
+
name length <= 120
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
status active
|
|
28
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
entity entity_task {
|
|
2
|
+
name "Task"
|
|
3
|
+
description "A unit of work tracked in the Todo domain and surfaced in the generated demo"
|
|
4
|
+
|
|
5
|
+
fields {
|
|
6
|
+
id uuid required
|
|
7
|
+
title string required
|
|
8
|
+
description text optional
|
|
9
|
+
status task_status required default draft
|
|
10
|
+
priority task_priority required default medium
|
|
11
|
+
owner_id uuid optional
|
|
12
|
+
project_id uuid required
|
|
13
|
+
created_at datetime required
|
|
14
|
+
updated_at datetime required
|
|
15
|
+
completed_at datetime optional
|
|
16
|
+
due_at datetime optional
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
keys {
|
|
20
|
+
primary [id]
|
|
21
|
+
index [project_id, status]
|
|
22
|
+
index [owner_id, status]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
relations {
|
|
26
|
+
owner_id references entity_user.id
|
|
27
|
+
project_id references entity_project.id
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
invariants {
|
|
31
|
+
completed_at requires status == completed
|
|
32
|
+
status == active implies owner_id is required
|
|
33
|
+
status == draft implies completed_at is null
|
|
34
|
+
title length <= 200
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
status active
|
|
38
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
entity entity_user {
|
|
2
|
+
name "User"
|
|
3
|
+
description "A person who can own tasks"
|
|
4
|
+
|
|
5
|
+
fields {
|
|
6
|
+
id uuid required
|
|
7
|
+
email string required
|
|
8
|
+
display_name string required
|
|
9
|
+
is_active boolean required default true
|
|
10
|
+
created_at datetime required
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
keys {
|
|
14
|
+
primary [id]
|
|
15
|
+
unique [email]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
invariants {
|
|
19
|
+
email format == email
|
|
20
|
+
display_name length <= 120
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
status active
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
operation op_task_creation_monitoring {
|
|
2
|
+
name "Task creation monitoring"
|
|
3
|
+
description "Runtime monitoring for task creation"
|
|
4
|
+
|
|
5
|
+
observes [cap_create_task]
|
|
6
|
+
metrics [task_creation_latency, task_creation_failure_rate]
|
|
7
|
+
alerts [high_task_creation_failure_rate]
|
|
8
|
+
|
|
9
|
+
status active
|
|
10
|
+
}
|