@astrale-domains/issues 0.1.2 → 0.1.3

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +71 -15
  3. package/dist/schema/.runtime/states/issue/index.d.ts +30 -0
  4. package/dist/schema/.runtime/states/issue/index.js +11 -0
  5. package/dist/schema/comment/class.d.ts +35 -3
  6. package/dist/schema/comment/class.js +11 -2
  7. package/dist/schema/comment/contribute-to-comment-policy.d.ts +1 -0
  8. package/dist/schema/comment/contribute-to-comment-policy.js +12 -0
  9. package/dist/schema/comment/edit-own-comment-policy.d.ts +1 -0
  10. package/dist/schema/comment/edit-own-comment-policy.js +6 -0
  11. package/dist/schema/comment/index.d.ts +3 -0
  12. package/dist/schema/comment/index.js +3 -0
  13. package/dist/schema/comment/methods.js +18 -0
  14. package/dist/schema/comment/relationships.d.ts +4 -4
  15. package/dist/schema/comment/relationships.js +10 -5
  16. package/dist/schema/comment/traverse-comment-relationship-policy.d.ts +2 -0
  17. package/dist/schema/comment/traverse-comment-relationship-policy.js +17 -0
  18. package/dist/schema/index.d.ts +5 -6
  19. package/dist/schema/index.js +4 -5
  20. package/dist/schema/issue/class.d.ts +163 -4
  21. package/dist/schema/issue/class.js +21 -9
  22. package/dist/schema/issue/contribute-to-issue-policy.d.ts +1 -0
  23. package/dist/schema/issue/contribute-to-issue-policy.js +10 -0
  24. package/dist/schema/issue/index.d.ts +3 -1
  25. package/dist/schema/issue/index.js +3 -1
  26. package/dist/schema/issue/methods.js +66 -0
  27. package/dist/schema/issue/relationships.d.ts +15 -60
  28. package/dist/schema/issue/relationships.js +21 -15
  29. package/dist/schema/issue/traverse-issue-relationship-policy.d.ts +5 -0
  30. package/dist/schema/issue/traverse-issue-relationship-policy.js +55 -0
  31. package/dist/schema/project/class.d.ts +234 -0
  32. package/dist/schema/project/class.js +27 -0
  33. package/dist/schema/project/contribute-to-project-policy.d.ts +1 -0
  34. package/dist/schema/project/contribute-to-project-policy.js +6 -0
  35. package/dist/schema/project/index.d.ts +5 -0
  36. package/dist/schema/project/index.js +5 -0
  37. package/dist/schema/project/manage-project-policy.d.ts +1 -0
  38. package/dist/schema/project/manage-project-policy.js +6 -0
  39. package/dist/schema/project/methods.js +68 -0
  40. package/dist/schema/{command → project}/relationships.d.ts +9 -9
  41. package/dist/schema/project/relationships.js +15 -0
  42. package/dist/schema/project/traverse-project-relationship-policy.d.ts +4 -0
  43. package/dist/schema/project/traverse-project-relationship-policy.js +20 -0
  44. package/dist/schema/{application/index.d.ts → schema.d.ts} +454 -335
  45. package/dist/schema/schema.js +44 -0
  46. package/dist/schema/tag/class.d.ts +39 -2
  47. package/dist/schema/tag/class.js +6 -1
  48. package/dist/schema/tag/contribute-to-tag-policy.d.ts +1 -0
  49. package/dist/schema/tag/contribute-to-tag-policy.js +10 -0
  50. package/dist/schema/tag/index.d.ts +3 -1
  51. package/dist/schema/tag/index.js +3 -1
  52. package/dist/schema/tag/manage-tag-policy.d.ts +1 -0
  53. package/dist/schema/tag/manage-tag-policy.js +10 -0
  54. package/dist/schema/tag/methods.js +21 -0
  55. package/dist/schema/tag/relationships.d.ts +2 -2
  56. package/dist/schema/tag/relationships.js +11 -7
  57. package/dist/schema/value/index.js +34 -0
  58. package/package.json +16 -6
  59. package/dist/schema/application/functions.js +0 -156
  60. package/dist/schema/application/index.js +0 -49
  61. package/dist/schema/command/class.d.ts +0 -38
  62. package/dist/schema/command/class.js +0 -13
  63. package/dist/schema/command/index.d.ts +0 -2
  64. package/dist/schema/command/index.js +0 -2
  65. package/dist/schema/command/relationships.js +0 -14
  66. package/dist/schema/tracker/class.d.ts +0 -73
  67. package/dist/schema/tracker/class.js +0 -10
  68. package/dist/schema/tracker/index.d.ts +0 -2
  69. package/dist/schema/tracker/index.js +0 -2
  70. package/dist/schema/tracker/relationships.d.ts +0 -16
  71. package/dist/schema/tracker/relationships.js +0 -7
@@ -52,11 +52,96 @@ export declare const Issue: import("@astrale-os/sdk/schema").NodeClass<{
52
52
  }, "kernel.astrale.ai:class.Node", readonly import("@astrale-os/sdk/schema").AnyResolvedClass[], never, never, never, never, never, never>, ...never[]], import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "createdAt", "kernel.astrale.ai:class.Timestamped.property.createdAt"> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "updatedAt", "kernel.astrale.ai:class.Timestamped.property.updatedAt">, never, never, import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "createdAt", "kernel.astrale.ai:class.Timestamped.property.createdAt"> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, true, "updatedAt", "kernel.astrale.ai:class.Timestamped.property.updatedAt">, never, never>];
53
53
  readonly properties: {
54
54
  readonly reference: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "reference", "self">;
55
- readonly status: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<"canceled" | "in_progress" | "open" | "resolved", "canceled" | "in_progress" | "open" | "resolved", true, "status", "self">;
55
+ readonly reporterId: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "reporterId", "self">;
56
+ readonly assigneeId: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string | undefined, string | undefined, false, "assigneeId", "self">;
57
+ readonly status: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<unknown, "accepted" | "closed" | "deferred" | "open" | "resolved", false, "status", "self">;
56
58
  readonly priority: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<number, number, true, "priority", "self">;
59
+ readonly archived: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<boolean, boolean, true, "archived", "self">;
57
60
  };
58
- readonly methods: Readonly<Record<never, never>>;
59
- readonly effectiveProperties: (import("@astrale-os/sdk/schema").AuthoredPropertyProjection<number, number, true, "priority", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "reference", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<"canceled" | "in_progress" | "open" | "resolved", "canceled" | "in_progress" | "open" | "resolved", true, "status", "self">) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false> & {
61
+ readonly methods: {
62
+ readonly update: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
63
+ title?: string | undefined;
64
+ description?: string | undefined;
65
+ priority?: number | undefined;
66
+ }, {
67
+ readonly mode: 'value';
68
+ readonly value: {
69
+ id: string;
70
+ reference: string;
71
+ title: string;
72
+ description: string;
73
+ status: "accepted" | "closed" | "deferred" | "open" | "resolved";
74
+ priority: number;
75
+ archived: boolean;
76
+ };
77
+ }, "authorized", false, "default">>;
78
+ readonly transition: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
79
+ event: unknown;
80
+ }, {
81
+ readonly mode: 'value';
82
+ readonly value: {
83
+ kind: "transitioned";
84
+ issue: {
85
+ id: string;
86
+ reference: string;
87
+ title: string;
88
+ description: string;
89
+ status: "accepted" | "closed" | "deferred" | "open" | "resolved";
90
+ priority: number;
91
+ archived: boolean;
92
+ };
93
+ } | {
94
+ kind: "rejected";
95
+ code: "STATE_TRANSITION_ILLEGAL";
96
+ from: "accepted" | "closed" | "deferred" | "open" | "resolved";
97
+ event: "accept" | "close" | "defer" | "reopen" | "resolve";
98
+ };
99
+ }, "authorized", false, "default">>;
100
+ readonly assign: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
101
+ assigneeId: string | null;
102
+ }, {
103
+ readonly mode: 'value';
104
+ readonly value: {
105
+ issueId: string;
106
+ assigneeId?: string | undefined;
107
+ };
108
+ }, "authorized", false, "default">>;
109
+ readonly setTags: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
110
+ tagIds: string[];
111
+ }, {
112
+ readonly mode: 'value';
113
+ readonly value: {
114
+ issueId: string;
115
+ tagIds: string[];
116
+ };
117
+ }, "authorized", false, "default">>;
118
+ readonly setParent: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
119
+ parentId: string | null;
120
+ }, {
121
+ readonly mode: 'value';
122
+ readonly value: {
123
+ issueId: string;
124
+ parentId?: string | undefined;
125
+ };
126
+ }, "authorized", false, "default">>;
127
+ readonly addComment: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
128
+ body: string;
129
+ }, {
130
+ readonly mode: 'value';
131
+ readonly value: {
132
+ id: string;
133
+ body: string;
134
+ };
135
+ }, "authorized", false, "default">>;
136
+ readonly archive: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
137
+ readonly mode: 'value';
138
+ readonly value: {
139
+ issueId: string;
140
+ archived: true;
141
+ };
142
+ }, "authorized", false, "default">>;
143
+ };
144
+ readonly effectiveProperties: (import("@astrale-os/sdk/schema").AuthoredPropertyProjection<boolean, boolean, true, "archived", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string | undefined, string | undefined, false, "assigneeId", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<number, number, true, "priority", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "reference", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, true, "reporterId", "self"> | import("@astrale-os/sdk/schema").AuthoredPropertyProjection<unknown, "accepted" | "closed" | "deferred" | "open" | "resolved", false, "status", "self">) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false> & {
60
145
  readonly name: "description";
61
146
  readonly key: "kernel.astrale.ai:class.Descriptable.property.description";
62
147
  }) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, true> & {
@@ -69,6 +154,80 @@ export declare const Issue: import("@astrale-os/sdk/schema").NodeClass<{
69
154
  readonly name: "updatedAt";
70
155
  readonly key: "kernel.astrale.ai:class.Timestamped.property.updatedAt";
71
156
  });
72
- readonly effectiveInstanceMethods: never;
157
+ readonly effectiveInstanceMethods: import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
158
+ readonly mode: 'value';
159
+ readonly value: {
160
+ issueId: string;
161
+ archived: true;
162
+ };
163
+ }, "authorized", false, "default">>, "archive", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
164
+ title?: string | undefined;
165
+ description?: string | undefined;
166
+ priority?: number | undefined;
167
+ }, {
168
+ readonly mode: 'value';
169
+ readonly value: {
170
+ id: string;
171
+ reference: string;
172
+ title: string;
173
+ description: string;
174
+ status: "accepted" | "closed" | "deferred" | "open" | "resolved";
175
+ priority: number;
176
+ archived: boolean;
177
+ };
178
+ }, "authorized", false, "default">>, "update", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
179
+ event: unknown;
180
+ }, {
181
+ readonly mode: 'value';
182
+ readonly value: {
183
+ kind: "transitioned";
184
+ issue: {
185
+ id: string;
186
+ reference: string;
187
+ title: string;
188
+ description: string;
189
+ status: "accepted" | "closed" | "deferred" | "open" | "resolved";
190
+ priority: number;
191
+ archived: boolean;
192
+ };
193
+ } | {
194
+ kind: "rejected";
195
+ code: "STATE_TRANSITION_ILLEGAL";
196
+ from: "accepted" | "closed" | "deferred" | "open" | "resolved";
197
+ event: "accept" | "close" | "defer" | "reopen" | "resolve";
198
+ };
199
+ }, "authorized", false, "default">>, "transition", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
200
+ assigneeId: string | null;
201
+ }, {
202
+ readonly mode: 'value';
203
+ readonly value: {
204
+ issueId: string;
205
+ assigneeId?: string | undefined;
206
+ };
207
+ }, "authorized", false, "default">>, "assign", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
208
+ tagIds: string[];
209
+ }, {
210
+ readonly mode: 'value';
211
+ readonly value: {
212
+ issueId: string;
213
+ tagIds: string[];
214
+ };
215
+ }, "authorized", false, "default">>, "setTags", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
216
+ parentId: string | null;
217
+ }, {
218
+ readonly mode: 'value';
219
+ readonly value: {
220
+ issueId: string;
221
+ parentId?: string | undefined;
222
+ };
223
+ }, "authorized", false, "default">>, "setParent", "self"> | import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
224
+ body: string;
225
+ }, {
226
+ readonly mode: 'value';
227
+ readonly value: {
228
+ id: string;
229
+ body: string;
230
+ };
231
+ }, "authorized", false, "default">>, "addComment", "self">;
73
232
  readonly effectiveStaticMethods: never;
74
233
  }>;
@@ -1,17 +1,29 @@
1
- import { K, nodeClass } from '@astrale-os/sdk/schema';
1
+ import { K, nodeClass, property } from '@astrale-os/sdk/schema';
2
2
  import { z } from 'zod';
3
- const statuses = [
4
- 'open',
5
- 'in_progress',
6
- 'resolved',
7
- 'canceled',
8
- ];
3
+ import { nodeIdValue } from '../value/index.js';
4
+ import { issueLifecycle } from '../.runtime/states/issue/index.js';
5
+ import { ContributeToIssue } from './contribute-to-issue-policy.js';
6
+ import { addIssueCommentMethod, archiveIssueMethod, assignIssueMethod, setIssueParentMethod, setIssueTagsMethod, transitionIssueMethod, updateIssueMethod, } from './methods.js';
9
7
  export const Issue = nodeClass({
10
- description: 'One numbered work item contained by exactly one Tracker.',
8
+ description: 'One immutable-reference work item contained by exactly one Project.',
9
+ icon: 'circle-dot',
11
10
  extends: [K.classes.Named, K.classes.Descriptable, K.classes.Timestamped],
12
11
  properties: {
13
12
  reference: z.string().min(1).max(32),
14
- status: z.enum(statuses),
13
+ reporterId: property(nodeIdValue, { visibility: 'private' }),
14
+ assigneeId: property(nodeIdValue.optional(), { visibility: 'private' }),
15
+ status: issueLifecycle.stateSchema,
15
16
  priority: z.number().int().min(0).max(4),
17
+ archived: z.boolean(),
16
18
  },
19
+ methods: {
20
+ update: updateIssueMethod,
21
+ transition: transitionIssueMethod,
22
+ assign: assignIssueMethod,
23
+ setTags: setIssueTagsMethod,
24
+ setParent: setIssueParentMethod,
25
+ addComment: addIssueCommentMethod,
26
+ archive: archiveIssueMethod,
27
+ },
28
+ policies: { read: () => ContributeToIssue },
17
29
  });
@@ -0,0 +1 @@
1
+ export declare const ContributeToIssue: import("@astrale-os/sdk/schema").Policy;
@@ -0,0 +1,10 @@
1
+ import { policy } from '@astrale-os/sdk/schema';
2
+ import { Project, project_has_member, project_owned_by } from '../project/index.js';
3
+ import { project_contains_issue } from './relationships.js';
4
+ export const ContributeToIssue = policy({
5
+ description: 'The caller owns or belongs to the Project containing this Issue.',
6
+ match: ({ allOf, anyOf, edge, exists, object, subject }) => exists(({ node }) => {
7
+ const project = node(() => Project);
8
+ return allOf(anyOf(edge({ source: subject, class: () => project_owned_by, target: project }), edge({ source: subject, class: () => project_has_member, target: project })), edge({ source: project, class: () => project_contains_issue, target: object }));
9
+ }),
10
+ });
@@ -1,2 +1,4 @@
1
1
  export { Issue } from './class.js';
2
- export { issue_assigned_to, issue_blocks, issue_duplicates, issue_relates_to, issue_reported_by, issue_subtask_of, tracker_contains_issue, } from './relationships.js';
2
+ export { ContributeToIssue } from './contribute-to-issue-policy.js';
3
+ export { issue_assigned_to, issue_reported_by, issue_subtask_of, project_contains_issue, } from './relationships.js';
4
+ export { TraverseIssueAssignee, TraverseIssueComment, TraverseIssueParent, TraverseIssueReporter, TraverseIssueTag, } from './traverse-issue-relationship-policy.js';
@@ -1,2 +1,4 @@
1
1
  export { Issue } from './class.js';
2
- export { issue_assigned_to, issue_blocks, issue_duplicates, issue_relates_to, issue_reported_by, issue_subtask_of, tracker_contains_issue, } from './relationships.js';
2
+ export { ContributeToIssue } from './contribute-to-issue-policy.js';
3
+ export { issue_assigned_to, issue_reported_by, issue_subtask_of, project_contains_issue, } from './relationships.js';
4
+ export { TraverseIssueAssignee, TraverseIssueComment, TraverseIssueParent, TraverseIssueReporter, TraverseIssueTag, } from './traverse-issue-relationship-policy.js';
@@ -0,0 +1,66 @@
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { commentValue, issueValue, nodeIdValue } from '../value/index.js';
4
+ import { issueLifecycle } from '../.runtime/states/issue/index.js';
5
+ import { ContributeToIssue } from './contribute-to-issue-policy.js';
6
+ export const updateIssueMethod = method({
7
+ description: 'Update mutable Issue fields.',
8
+ auth: 'authorized',
9
+ policy: ({ check, self }) => check(ContributeToIssue, self),
10
+ input: z.strictObject({
11
+ title: z.string().min(1).max(200).optional(),
12
+ description: z.string().max(50_000).optional(),
13
+ priority: z.number().int().min(0).max(4).optional(),
14
+ }),
15
+ output: issueValue,
16
+ });
17
+ export const transitionIssueMethod = method({
18
+ description: 'Apply one legal Issue lifecycle event.',
19
+ auth: 'authorized',
20
+ policy: ({ check, self }) => check(ContributeToIssue, self),
21
+ input: z.strictObject({ event: issueLifecycle.eventSchema }),
22
+ output: z.discriminatedUnion('kind', [
23
+ z.strictObject({ kind: z.literal('transitioned'), issue: issueValue }),
24
+ z.strictObject({
25
+ kind: z.literal('rejected'),
26
+ code: z.literal('STATE_TRANSITION_ILLEGAL'),
27
+ from: issueLifecycle.stateSchema,
28
+ event: issueLifecycle.eventSchema,
29
+ }),
30
+ ]),
31
+ });
32
+ export const assignIssueMethod = method({
33
+ description: 'Assign this Issue to a Project participant or clear its assignee.',
34
+ auth: 'authorized',
35
+ policy: ({ check, self }) => check(ContributeToIssue, self),
36
+ input: z.strictObject({ assigneeId: nodeIdValue.nullable() }),
37
+ output: z.strictObject({ issueId: nodeIdValue, assigneeId: nodeIdValue.optional() }),
38
+ });
39
+ export const setIssueTagsMethod = method({
40
+ description: 'Replace this Issue Tag set with an exact Project-local set.',
41
+ auth: 'authorized',
42
+ policy: ({ check, self }) => check(ContributeToIssue, self),
43
+ input: z.strictObject({ tagIds: z.array(nodeIdValue).max(128) }),
44
+ output: z.strictObject({ issueId: nodeIdValue, tagIds: z.array(nodeIdValue) }),
45
+ });
46
+ export const setIssueParentMethod = method({
47
+ description: 'Set or clear this Issue parent inside the same Project.',
48
+ auth: 'authorized',
49
+ policy: ({ check, self }) => check(ContributeToIssue, self),
50
+ input: z.strictObject({ parentId: nodeIdValue.nullable() }),
51
+ output: z.strictObject({ issueId: nodeIdValue, parentId: nodeIdValue.optional() }),
52
+ });
53
+ export const addIssueCommentMethod = method({
54
+ description: 'Add one authored Comment to this Issue.',
55
+ auth: 'authorized',
56
+ policy: ({ check, self }) => check(ContributeToIssue, self),
57
+ input: z.strictObject({ body: z.string().min(1).max(50_000) }),
58
+ output: commentValue,
59
+ });
60
+ export const archiveIssueMethod = method({
61
+ description: 'Archive this Issue without deleting its discussion or relationships.',
62
+ auth: 'authorized',
63
+ policy: ({ check, self }) => check(ContributeToIssue, self),
64
+ input: z.strictObject({}),
65
+ output: z.strictObject({ issueId: nodeIdValue, archived: z.literal(true) }),
66
+ });
@@ -1,10 +1,10 @@
1
- export declare const tracker_contains_issue: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
1
+ export declare const project_contains_issue: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
2
2
  readonly depth: 0;
3
3
  readonly abstract: false;
4
4
  readonly extends: readonly [];
5
5
  readonly properties: never;
6
6
  readonly source: {
7
- readonly as: "tracker";
7
+ readonly as: "project";
8
8
  readonly outgoing: "0..*";
9
9
  };
10
10
  readonly target: {
@@ -20,76 +20,28 @@ export declare const issue_reported_by: import("@astrale-os/sdk/schema").Directe
20
20
  readonly extends: readonly [];
21
21
  readonly properties: never;
22
22
  readonly source: {
23
- readonly as: "issue";
24
- readonly outgoing: "1";
25
- };
26
- readonly target: {
27
23
  readonly as: "reporter";
28
- readonly incoming: "0..*";
29
- };
30
- readonly constraints: Record<never, never>;
31
- readonly effectiveProperties: never;
32
- }>;
33
- export declare const issue_assigned_to: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
34
- readonly depth: 0;
35
- readonly abstract: false;
36
- readonly extends: readonly [];
37
- readonly properties: never;
38
- readonly source: {
39
- readonly as: "issue";
40
- readonly outgoing: "0..1";
41
- };
42
- readonly target: {
43
- readonly as: "assignee";
44
- readonly incoming: "0..*";
45
- };
46
- readonly constraints: Record<never, never>;
47
- readonly effectiveProperties: never;
48
- }>;
49
- export declare const issue_blocks: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
50
- readonly depth: 0;
51
- readonly abstract: false;
52
- readonly extends: readonly [];
53
- readonly properties: never;
54
- readonly source: {
55
- readonly as: "source";
56
- readonly outgoing: "0..*";
57
- };
58
- readonly target: {
59
- readonly as: "target";
60
- readonly incoming: "0..*";
61
- };
62
- readonly constraints: Record<never, never>;
63
- readonly effectiveProperties: never;
64
- }>;
65
- export declare const issue_duplicates: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
66
- readonly depth: 0;
67
- readonly abstract: false;
68
- readonly extends: readonly [];
69
- readonly properties: never;
70
- readonly source: {
71
- readonly as: "source";
72
24
  readonly outgoing: "0..*";
73
25
  };
74
26
  readonly target: {
75
- readonly as: "target";
76
- readonly incoming: "0..*";
27
+ readonly as: "issue";
28
+ readonly incoming: "1";
77
29
  };
78
30
  readonly constraints: Record<never, never>;
79
31
  readonly effectiveProperties: never;
80
32
  }>;
81
- export declare const issue_relates_to: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
33
+ export declare const issue_assigned_to: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
82
34
  readonly depth: 0;
83
35
  readonly abstract: false;
84
36
  readonly extends: readonly [];
85
37
  readonly properties: never;
86
38
  readonly source: {
87
- readonly as: "source";
39
+ readonly as: "assignee";
88
40
  readonly outgoing: "0..*";
89
41
  };
90
42
  readonly target: {
91
- readonly as: "target";
92
- readonly incoming: "0..*";
43
+ readonly as: "issue";
44
+ readonly incoming: "0..1";
93
45
  };
94
46
  readonly constraints: Record<never, never>;
95
47
  readonly effectiveProperties: never;
@@ -100,13 +52,16 @@ export declare const issue_subtask_of: import("@astrale-os/sdk/schema").Directed
100
52
  readonly extends: readonly [];
101
53
  readonly properties: never;
102
54
  readonly source: {
103
- readonly as: "source";
104
- readonly outgoing: "0..*";
55
+ readonly as: "child";
56
+ readonly outgoing: "0..1";
105
57
  };
106
58
  readonly target: {
107
- readonly as: "target";
59
+ readonly as: "parent";
108
60
  readonly incoming: "0..*";
109
61
  };
110
- readonly constraints: Record<never, never>;
62
+ readonly constraints: {
63
+ readonly noSelf: true;
64
+ readonly acyclic: true;
65
+ };
111
66
  readonly effectiveProperties: never;
112
67
  }>;
@@ -1,23 +1,29 @@
1
1
  import { K, edgeClass } from '@astrale-os/sdk/schema';
2
- import { Tracker } from '#schema/tracker';
2
+ import { Project, TraverseProjectIssue } from '../project/index.js';
3
3
  import { Issue } from './class.js';
4
- export const tracker_contains_issue = edgeClass.directed({
5
- source: { as: 'tracker', accepts: [Tracker], outgoing: '0..*' },
6
- target: { as: 'issue', accepts: [Issue], incoming: '1' },
4
+ import { TraverseIssueAssignee, TraverseIssueParent, TraverseIssueReporter, } from './traverse-issue-relationship-policy.js';
5
+ export const project_contains_issue = edgeClass.directed({
6
+ description: 'One Project contains and numbers one Issue.',
7
+ source: { as: 'project', accepts: [() => Project], outgoing: '0..*' },
8
+ target: { as: 'issue', accepts: [() => Issue], incoming: '1' },
9
+ policies: { traverse: () => TraverseProjectIssue },
7
10
  });
8
11
  export const issue_reported_by = edgeClass.directed({
9
- source: { as: 'issue', accepts: [Issue], outgoing: '1' },
10
- target: { as: 'reporter', accepts: [K.classes.Identity], incoming: '0..*' },
12
+ description: 'The immutable reporter of one Issue.',
13
+ source: { as: 'reporter', accepts: [K.classes.Identity], outgoing: '0..*' },
14
+ target: { as: 'issue', accepts: [() => Issue], incoming: '1' },
15
+ policies: { traverse: () => TraverseIssueReporter },
11
16
  });
12
17
  export const issue_assigned_to = edgeClass.directed({
13
- source: { as: 'issue', accepts: [Issue], outgoing: '0..1' },
14
- target: { as: 'assignee', accepts: [K.classes.Identity], incoming: '0..*' },
18
+ description: 'The optional current assignee of one Issue.',
19
+ source: { as: 'assignee', accepts: [K.classes.Identity], outgoing: '0..*' },
20
+ target: { as: 'issue', accepts: [() => Issue], incoming: '0..1' },
21
+ policies: { traverse: () => TraverseIssueAssignee },
15
22
  });
16
- const relation = () => edgeClass.directed({
17
- source: { as: 'source', accepts: [Issue], outgoing: '0..*' },
18
- target: { as: 'target', accepts: [Issue], incoming: '0..*' },
23
+ export const issue_subtask_of = edgeClass.directed({
24
+ description: 'One Issue is an acyclic subtask of at most one Issue in the same Project.',
25
+ source: { as: 'child', accepts: [() => Issue], outgoing: '0..1' },
26
+ target: { as: 'parent', accepts: [() => Issue], incoming: '0..*' },
27
+ constraints: { noSelf: true, acyclic: true },
28
+ policies: { traverse: () => TraverseIssueParent },
19
29
  });
20
- export const issue_blocks = relation();
21
- export const issue_duplicates = relation();
22
- export const issue_relates_to = relation();
23
- export const issue_subtask_of = relation();
@@ -0,0 +1,5 @@
1
+ export declare const TraverseIssueReporter: import("@astrale-os/sdk/schema").Policy;
2
+ export declare const TraverseIssueAssignee: import("@astrale-os/sdk/schema").Policy;
3
+ export declare const TraverseIssueParent: import("@astrale-os/sdk/schema").Policy;
4
+ export declare const TraverseIssueComment: import("@astrale-os/sdk/schema").Policy;
5
+ export declare const TraverseIssueTag: import("@astrale-os/sdk/schema").Policy;
@@ -0,0 +1,55 @@
1
+ import { policy } from '@astrale-os/sdk/schema';
2
+ import { issue_has_comment } from '../comment/index.js';
3
+ import { Project, project_has_member, project_owned_by } from '../project/index.js';
4
+ import { issue_tagged_with } from '../tag/index.js';
5
+ import { issue_assigned_to, issue_reported_by, issue_subtask_of, project_contains_issue, } from './relationships.js';
6
+ export const TraverseIssueReporter = policy({
7
+ description: 'Issue reporter relationships are visible only inside the containing Project.',
8
+ match: ({ allOf, anyOf, edge, exists, source, subject, target }) => anyOf(exists(({ node }) => {
9
+ const project = node(() => Project);
10
+ return allOf(edge({ source, class: () => issue_reported_by, target }), edge({ source: project, class: () => project_contains_issue, target }), edge({ source: subject, class: () => project_owned_by, target: project }));
11
+ }), exists(({ node }) => {
12
+ const project = node(() => Project);
13
+ return allOf(edge({ source, class: () => issue_reported_by, target }), edge({ source: project, class: () => project_contains_issue, target }), edge({ source: subject, class: () => project_has_member, target: project }));
14
+ })),
15
+ });
16
+ export const TraverseIssueAssignee = policy({
17
+ description: 'Issue assignment relationships are visible only inside the containing Project.',
18
+ match: ({ allOf, anyOf, edge, exists, source, subject, target }) => anyOf(exists(({ node }) => {
19
+ const project = node(() => Project);
20
+ return allOf(edge({ source, class: () => issue_assigned_to, target }), edge({ source: project, class: () => project_contains_issue, target }), edge({ source: subject, class: () => project_owned_by, target: project }));
21
+ }), exists(({ node }) => {
22
+ const project = node(() => Project);
23
+ return allOf(edge({ source, class: () => issue_assigned_to, target }), edge({ source: project, class: () => project_contains_issue, target }), edge({ source: subject, class: () => project_has_member, target: project }));
24
+ })),
25
+ });
26
+ export const TraverseIssueParent = policy({
27
+ description: 'Issue parent relationships are visible only inside the containing Project.',
28
+ match: ({ allOf, anyOf, edge, exists, source, subject, target }) => anyOf(exists(({ node }) => {
29
+ const project = node(() => Project);
30
+ return allOf(edge({ source, class: () => issue_subtask_of, target }), edge({ source: project, class: () => project_contains_issue, target: source }), edge({ source: subject, class: () => project_owned_by, target: project }));
31
+ }), exists(({ node }) => {
32
+ const project = node(() => Project);
33
+ return allOf(edge({ source, class: () => issue_subtask_of, target }), edge({ source: project, class: () => project_contains_issue, target: source }), edge({ source: subject, class: () => project_has_member, target: project }));
34
+ })),
35
+ });
36
+ export const TraverseIssueComment = policy({
37
+ description: 'Issue Comment containment is visible only inside the containing Project.',
38
+ match: ({ allOf, anyOf, edge, exists, source, subject, target }) => anyOf(exists(({ node }) => {
39
+ const project = node(() => Project);
40
+ return allOf(edge({ source, class: () => issue_has_comment, target }), edge({ source: project, class: () => project_contains_issue, target: source }), edge({ source: subject, class: () => project_owned_by, target: project }));
41
+ }), exists(({ node }) => {
42
+ const project = node(() => Project);
43
+ return allOf(edge({ source, class: () => issue_has_comment, target }), edge({ source: project, class: () => project_contains_issue, target: source }), edge({ source: subject, class: () => project_has_member, target: project }));
44
+ })),
45
+ });
46
+ export const TraverseIssueTag = policy({
47
+ description: 'Issue Tag relationships are visible only inside the containing Project.',
48
+ match: ({ allOf, anyOf, edge, exists, source, subject, target }) => anyOf(exists(({ node }) => {
49
+ const project = node(() => Project);
50
+ return allOf(edge({ source, class: () => issue_tagged_with, target }), edge({ source: project, class: () => project_contains_issue, target: source }), edge({ source: subject, class: () => project_owned_by, target: project }));
51
+ }), exists(({ node }) => {
52
+ const project = node(() => Project);
53
+ return allOf(edge({ source, class: () => issue_tagged_with, target }), edge({ source: project, class: () => project_contains_issue, target: source }), edge({ source: subject, class: () => project_has_member, target: project }));
54
+ })),
55
+ });