@voyantjs/legal 0.1.0
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/LICENSE +109 -0
- package/README.md +60 -0
- package/dist/contracts/index.d.ts +13 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +19 -0
- package/dist/contracts/routes.d.ts +1297 -0
- package/dist/contracts/routes.d.ts.map +1 -0
- package/dist/contracts/routes.js +224 -0
- package/dist/contracts/schema.d.ts +1531 -0
- package/dist/contracts/schema.d.ts.map +1 -0
- package/dist/contracts/schema.js +227 -0
- package/dist/contracts/service.d.ts +1753 -0
- package/dist/contracts/service.d.ts.map +1 -0
- package/dist/contracts/service.js +570 -0
- package/dist/contracts/validation.d.ts +274 -0
- package/dist/contracts/validation.d.ts.map +1 -0
- package/dist/contracts/validation.js +125 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/policies/index.d.ts +16 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +26 -0
- package/dist/policies/routes.d.ts +916 -0
- package/dist/policies/routes.d.ts.map +1 -0
- package/dist/policies/routes.js +162 -0
- package/dist/policies/schema.d.ts +1176 -0
- package/dist/policies/schema.d.ts.map +1 -0
- package/dist/policies/schema.js +189 -0
- package/dist/policies/service.d.ts +1384 -0
- package/dist/policies/service.d.ts.map +1 -0
- package/dist/policies/service.js +438 -0
- package/dist/policies/validation.d.ts +273 -0
- package/dist/policies/validation.d.ts.map +1 -0
- package/dist/policies/validation.js +140 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/contracts/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAoBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAMD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAqP7B,CAAA;AAEJ,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAA;AAO9D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAkB9B,CAAA;AAEJ,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { contractsService } from "./service.js";
|
|
3
|
+
import { contractListQuerySchema, contractTemplateListQuerySchema, insertContractAttachmentSchema, insertContractNumberSeriesSchema, insertContractSchema, insertContractSignatureSchema, insertContractTemplateSchema, insertContractTemplateVersionSchema, renderTemplateInputSchema, updateContractAttachmentSchema, updateContractNumberSeriesSchema, updateContractSchema, updateContractTemplateSchema, } from "./validation.js";
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Contracts admin routes — `/v1/admin/contracts/*`
|
|
6
|
+
// ============================================================================
|
|
7
|
+
export const contractsAdminRoutes = new Hono()
|
|
8
|
+
// ---------- templates ----------
|
|
9
|
+
.get("/templates", async (c) => {
|
|
10
|
+
const query = contractTemplateListQuerySchema.parse(Object.fromEntries(new URL(c.req.url).searchParams));
|
|
11
|
+
return c.json(await contractsService.listTemplates(c.get("db"), query));
|
|
12
|
+
})
|
|
13
|
+
.post("/templates", async (c) => {
|
|
14
|
+
const row = await contractsService.createTemplate(c.get("db"), insertContractTemplateSchema.parse(await c.req.json()));
|
|
15
|
+
return c.json({ data: row }, 201);
|
|
16
|
+
})
|
|
17
|
+
.get("/templates/:id", async (c) => {
|
|
18
|
+
const row = await contractsService.getTemplateById(c.get("db"), c.req.param("id"));
|
|
19
|
+
if (!row)
|
|
20
|
+
return c.json({ error: "Template not found" }, 404);
|
|
21
|
+
return c.json({ data: row });
|
|
22
|
+
})
|
|
23
|
+
.patch("/templates/:id", async (c) => {
|
|
24
|
+
const row = await contractsService.updateTemplate(c.get("db"), c.req.param("id"), updateContractTemplateSchema.parse(await c.req.json()));
|
|
25
|
+
if (!row)
|
|
26
|
+
return c.json({ error: "Template not found" }, 404);
|
|
27
|
+
return c.json({ data: row });
|
|
28
|
+
})
|
|
29
|
+
.delete("/templates/:id", async (c) => {
|
|
30
|
+
const row = await contractsService.deleteTemplate(c.get("db"), c.req.param("id"));
|
|
31
|
+
if (!row)
|
|
32
|
+
return c.json({ error: "Template not found" }, 404);
|
|
33
|
+
return c.json({ success: true });
|
|
34
|
+
})
|
|
35
|
+
.post("/templates/:id/preview", async (c) => {
|
|
36
|
+
const input = renderTemplateInputSchema.parse(await c.req.json());
|
|
37
|
+
const template = await contractsService.getTemplateById(c.get("db"), c.req.param("id"));
|
|
38
|
+
if (!template)
|
|
39
|
+
return c.json({ error: "Template not found" }, 404);
|
|
40
|
+
const body = input.body ?? template.body;
|
|
41
|
+
const bodyFormat = input.bodyFormat ?? template.bodyFormat;
|
|
42
|
+
const rendered = contractsService.renderPreview({ ...input, body, bodyFormat });
|
|
43
|
+
return c.json({ data: { rendered, bodyFormat } });
|
|
44
|
+
})
|
|
45
|
+
// ---------- template versions ----------
|
|
46
|
+
.get("/templates/:id/versions", async (c) => {
|
|
47
|
+
const rows = await contractsService.listTemplateVersions(c.get("db"), c.req.param("id"));
|
|
48
|
+
return c.json({ data: rows });
|
|
49
|
+
})
|
|
50
|
+
.post("/templates/:id/versions", async (c) => {
|
|
51
|
+
const version = await contractsService.createTemplateVersion(c.get("db"), c.req.param("id"), insertContractTemplateVersionSchema.parse(await c.req.json()));
|
|
52
|
+
if (!version)
|
|
53
|
+
return c.json({ error: "Template not found" }, 404);
|
|
54
|
+
return c.json({ data: version }, 201);
|
|
55
|
+
})
|
|
56
|
+
.get("/template-versions/:id", async (c) => {
|
|
57
|
+
const row = await contractsService.getTemplateVersionById(c.get("db"), c.req.param("id"));
|
|
58
|
+
if (!row)
|
|
59
|
+
return c.json({ error: "Template version not found" }, 404);
|
|
60
|
+
return c.json({ data: row });
|
|
61
|
+
})
|
|
62
|
+
// ---------- number series ----------
|
|
63
|
+
.get("/number-series", async (c) => {
|
|
64
|
+
const rows = await contractsService.listSeries(c.get("db"));
|
|
65
|
+
return c.json({ data: rows });
|
|
66
|
+
})
|
|
67
|
+
.post("/number-series", async (c) => {
|
|
68
|
+
const row = await contractsService.createSeries(c.get("db"), insertContractNumberSeriesSchema.parse(await c.req.json()));
|
|
69
|
+
return c.json({ data: row }, 201);
|
|
70
|
+
})
|
|
71
|
+
.get("/number-series/:id", async (c) => {
|
|
72
|
+
const row = await contractsService.getSeriesById(c.get("db"), c.req.param("id"));
|
|
73
|
+
if (!row)
|
|
74
|
+
return c.json({ error: "Series not found" }, 404);
|
|
75
|
+
return c.json({ data: row });
|
|
76
|
+
})
|
|
77
|
+
.patch("/number-series/:id", async (c) => {
|
|
78
|
+
const row = await contractsService.updateSeries(c.get("db"), c.req.param("id"), updateContractNumberSeriesSchema.parse(await c.req.json()));
|
|
79
|
+
if (!row)
|
|
80
|
+
return c.json({ error: "Series not found" }, 404);
|
|
81
|
+
return c.json({ data: row });
|
|
82
|
+
})
|
|
83
|
+
.delete("/number-series/:id", async (c) => {
|
|
84
|
+
const row = await contractsService.deleteSeries(c.get("db"), c.req.param("id"));
|
|
85
|
+
if (!row)
|
|
86
|
+
return c.json({ error: "Series not found" }, 404);
|
|
87
|
+
return c.json({ success: true });
|
|
88
|
+
})
|
|
89
|
+
// ---------- contracts ----------
|
|
90
|
+
.get("/", async (c) => {
|
|
91
|
+
const query = contractListQuerySchema.parse(Object.fromEntries(new URL(c.req.url).searchParams));
|
|
92
|
+
return c.json(await contractsService.listContracts(c.get("db"), query));
|
|
93
|
+
})
|
|
94
|
+
.post("/", async (c) => {
|
|
95
|
+
const row = await contractsService.createContract(c.get("db"), insertContractSchema.parse(await c.req.json()));
|
|
96
|
+
return c.json({ data: row }, 201);
|
|
97
|
+
})
|
|
98
|
+
.get("/:id", async (c) => {
|
|
99
|
+
const row = await contractsService.getContractById(c.get("db"), c.req.param("id"));
|
|
100
|
+
if (!row)
|
|
101
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
102
|
+
return c.json({ data: row });
|
|
103
|
+
})
|
|
104
|
+
.patch("/:id", async (c) => {
|
|
105
|
+
const row = await contractsService.updateContract(c.get("db"), c.req.param("id"), updateContractSchema.parse(await c.req.json()));
|
|
106
|
+
if (!row)
|
|
107
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
108
|
+
return c.json({ data: row });
|
|
109
|
+
})
|
|
110
|
+
.delete("/:id", async (c) => {
|
|
111
|
+
const result = await contractsService.deleteContract(c.get("db"), c.req.param("id"));
|
|
112
|
+
if (result.status === "not_found")
|
|
113
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
114
|
+
if (result.status === "not_draft") {
|
|
115
|
+
return c.json({ error: "Only draft contracts can be deleted" }, 409);
|
|
116
|
+
}
|
|
117
|
+
return c.json({ success: true });
|
|
118
|
+
})
|
|
119
|
+
// ---------- lifecycle ----------
|
|
120
|
+
.post("/:id/issue", async (c) => {
|
|
121
|
+
const result = await contractsService.issueContract(c.get("db"), c.req.param("id"));
|
|
122
|
+
if (result.status === "not_found")
|
|
123
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
124
|
+
if (result.status === "not_draft") {
|
|
125
|
+
return c.json({ error: "Only draft contracts can be issued" }, 409);
|
|
126
|
+
}
|
|
127
|
+
return c.json({ data: result.contract });
|
|
128
|
+
})
|
|
129
|
+
.post("/:id/send", async (c) => {
|
|
130
|
+
const result = await contractsService.sendContract(c.get("db"), c.req.param("id"));
|
|
131
|
+
if (result.status === "not_found")
|
|
132
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
133
|
+
if (result.status === "not_issued") {
|
|
134
|
+
return c.json({ error: "Only issued/sent contracts can be sent" }, 409);
|
|
135
|
+
}
|
|
136
|
+
return c.json({ data: result.contract });
|
|
137
|
+
})
|
|
138
|
+
.post("/:id/sign", async (c) => {
|
|
139
|
+
const input = insertContractSignatureSchema.parse(await c.req.json());
|
|
140
|
+
const result = await contractsService.signContract(c.get("db"), c.req.param("id"), input);
|
|
141
|
+
if (result.status === "not_found")
|
|
142
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
143
|
+
if (result.status === "not_signable") {
|
|
144
|
+
return c.json({ error: "Contract is not in a signable state" }, 409);
|
|
145
|
+
}
|
|
146
|
+
return c.json({ data: { contract: result.contract, signature: result.signature } });
|
|
147
|
+
})
|
|
148
|
+
.post("/:id/execute", async (c) => {
|
|
149
|
+
const result = await contractsService.executeContract(c.get("db"), c.req.param("id"));
|
|
150
|
+
if (result.status === "not_found")
|
|
151
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
152
|
+
if (result.status === "not_signed") {
|
|
153
|
+
return c.json({ error: "Only signed contracts can be executed" }, 409);
|
|
154
|
+
}
|
|
155
|
+
return c.json({ data: result.contract });
|
|
156
|
+
})
|
|
157
|
+
.post("/:id/void", async (c) => {
|
|
158
|
+
const result = await contractsService.voidContract(c.get("db"), c.req.param("id"));
|
|
159
|
+
if (result.status === "not_found")
|
|
160
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
161
|
+
if (result.status === "already_void") {
|
|
162
|
+
return c.json({ error: "Contract is already void" }, 409);
|
|
163
|
+
}
|
|
164
|
+
return c.json({ data: result.contract });
|
|
165
|
+
})
|
|
166
|
+
.post("/:id/render", async (c) => {
|
|
167
|
+
const input = renderTemplateInputSchema.parse(await c.req.json());
|
|
168
|
+
const contract = await contractsService.getContractById(c.get("db"), c.req.param("id"));
|
|
169
|
+
if (!contract)
|
|
170
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
171
|
+
const rendered = contractsService.renderPreview(input);
|
|
172
|
+
return c.json({ data: { rendered } });
|
|
173
|
+
})
|
|
174
|
+
// ---------- signatures ----------
|
|
175
|
+
.get("/:id/signatures", async (c) => {
|
|
176
|
+
const rows = await contractsService.listSignatures(c.get("db"), c.req.param("id"));
|
|
177
|
+
return c.json({ data: rows });
|
|
178
|
+
})
|
|
179
|
+
// ---------- attachments ----------
|
|
180
|
+
.get("/:id/attachments", async (c) => {
|
|
181
|
+
const rows = await contractsService.listAttachments(c.get("db"), c.req.param("id"));
|
|
182
|
+
return c.json({ data: rows });
|
|
183
|
+
})
|
|
184
|
+
.post("/:id/attachments", async (c) => {
|
|
185
|
+
const row = await contractsService.createAttachment(c.get("db"), c.req.param("id"), insertContractAttachmentSchema.parse(await c.req.json()));
|
|
186
|
+
if (!row)
|
|
187
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
188
|
+
return c.json({ data: row }, 201);
|
|
189
|
+
})
|
|
190
|
+
.patch("/attachments/:attachmentId", async (c) => {
|
|
191
|
+
const row = await contractsService.updateAttachment(c.get("db"), c.req.param("attachmentId"), updateContractAttachmentSchema.parse(await c.req.json()));
|
|
192
|
+
if (!row)
|
|
193
|
+
return c.json({ error: "Attachment not found" }, 404);
|
|
194
|
+
return c.json({ data: row });
|
|
195
|
+
})
|
|
196
|
+
.delete("/attachments/:attachmentId", async (c) => {
|
|
197
|
+
const row = await contractsService.deleteAttachment(c.get("db"), c.req.param("attachmentId"));
|
|
198
|
+
if (!row)
|
|
199
|
+
return c.json({ error: "Attachment not found" }, 404);
|
|
200
|
+
return c.json({ success: true });
|
|
201
|
+
});
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// Contracts public routes — `/v1/public/contracts/*`
|
|
204
|
+
// Customer-facing: fetch own contract + self-sign
|
|
205
|
+
// ============================================================================
|
|
206
|
+
export const contractsPublicRoutes = new Hono()
|
|
207
|
+
.get("/:id", async (c) => {
|
|
208
|
+
const row = await contractsService.getContractById(c.get("db"), c.req.param("id"));
|
|
209
|
+
if (!row)
|
|
210
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
211
|
+
// Public view: omit sensitive metadata
|
|
212
|
+
const { metadata: _metadata, ...publicContract } = row;
|
|
213
|
+
return c.json({ data: publicContract });
|
|
214
|
+
})
|
|
215
|
+
.post("/:id/sign", async (c) => {
|
|
216
|
+
const input = insertContractSignatureSchema.parse(await c.req.json());
|
|
217
|
+
const result = await contractsService.signContract(c.get("db"), c.req.param("id"), input);
|
|
218
|
+
if (result.status === "not_found")
|
|
219
|
+
return c.json({ error: "Contract not found" }, 404);
|
|
220
|
+
if (result.status === "not_signable") {
|
|
221
|
+
return c.json({ error: "Contract is not in a signable state" }, 409);
|
|
222
|
+
}
|
|
223
|
+
return c.json({ data: { signature: result.signature } });
|
|
224
|
+
});
|