@ttctl/core 0.0.0 → 0.1.0-rc.1

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 (195) hide show
  1. package/README.md +49 -9
  2. package/dist/__generated__/gateway.d.ts +4546 -0
  3. package/dist/__generated__/gateway.d.ts.map +1 -0
  4. package/dist/__generated__/gateway.js +9 -0
  5. package/dist/__generated__/gateway.js.map +1 -0
  6. package/dist/__generated__/talent-profile-zod-schemas.d.ts +1187 -0
  7. package/dist/__generated__/talent-profile-zod-schemas.d.ts.map +1 -0
  8. package/dist/__generated__/talent-profile-zod-schemas.js +1136 -0
  9. package/dist/__generated__/talent-profile-zod-schemas.js.map +1 -0
  10. package/dist/__generated__/talent-profile.d.ts +1397 -0
  11. package/dist/__generated__/talent-profile.d.ts.map +1 -0
  12. package/dist/__generated__/talent-profile.js +9 -0
  13. package/dist/__generated__/talent-profile.js.map +1 -0
  14. package/dist/__generated__/zod-schemas.d.ts +2895 -0
  15. package/dist/__generated__/zod-schemas.d.ts.map +1 -0
  16. package/dist/__generated__/zod-schemas.js +3121 -0
  17. package/dist/__generated__/zod-schemas.js.map +1 -0
  18. package/dist/__tests__/fixtures/profile/builders.d.ts +74 -0
  19. package/dist/__tests__/fixtures/profile/builders.d.ts.map +1 -0
  20. package/dist/__tests__/fixtures/profile/builders.js +196 -0
  21. package/dist/__tests__/fixtures/profile/builders.js.map +1 -0
  22. package/dist/__tests__/fixtures/profile/data.d.ts +39 -0
  23. package/dist/__tests__/fixtures/profile/data.d.ts.map +1 -0
  24. package/dist/__tests__/fixtures/profile/data.js +230 -0
  25. package/dist/__tests__/fixtures/profile/data.js.map +1 -0
  26. package/dist/__tests__/fixtures/profile/index.d.ts +9 -0
  27. package/dist/__tests__/fixtures/profile/index.d.ts.map +1 -0
  28. package/dist/__tests__/fixtures/profile/index.js +10 -0
  29. package/dist/__tests__/fixtures/profile/index.js.map +1 -0
  30. package/dist/__tests__/fixtures/profile/types.d.ts +53 -0
  31. package/dist/__tests__/fixtures/profile/types.d.ts.map +1 -0
  32. package/dist/__tests__/fixtures/profile/types.js +4 -0
  33. package/dist/__tests__/fixtures/profile/types.js.map +1 -0
  34. package/dist/auth/errors.d.ts +82 -0
  35. package/dist/auth/errors.d.ts.map +1 -0
  36. package/dist/auth/errors.js +68 -0
  37. package/dist/auth/errors.js.map +1 -0
  38. package/dist/auth.d.ts +192 -0
  39. package/dist/auth.d.ts.map +1 -0
  40. package/dist/auth.js +294 -0
  41. package/dist/auth.js.map +1 -0
  42. package/dist/config.d.ts +212 -0
  43. package/dist/config.d.ts.map +1 -0
  44. package/dist/config.js +349 -0
  45. package/dist/config.js.map +1 -0
  46. package/dist/configLock.d.ts +50 -0
  47. package/dist/configLock.d.ts.map +1 -0
  48. package/dist/configLock.js +88 -0
  49. package/dist/configLock.js.map +1 -0
  50. package/dist/configWriter.d.ts +97 -0
  51. package/dist/configWriter.d.ts.map +1 -0
  52. package/dist/configWriter.js +687 -0
  53. package/dist/configWriter.js.map +1 -0
  54. package/dist/index.d.ts +37 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +28 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/kill-switch.d.ts +161 -0
  59. package/dist/kill-switch.d.ts.map +1 -0
  60. package/dist/kill-switch.js +235 -0
  61. package/dist/kill-switch.js.map +1 -0
  62. package/dist/lib/date.d.ts +58 -0
  63. package/dist/lib/date.d.ts.map +1 -0
  64. package/dist/lib/date.js +104 -0
  65. package/dist/lib/date.js.map +1 -0
  66. package/dist/lib/diagnostic-log.d.ts +159 -0
  67. package/dist/lib/diagnostic-log.d.ts.map +1 -0
  68. package/dist/lib/diagnostic-log.js +186 -0
  69. package/dist/lib/diagnostic-log.js.map +1 -0
  70. package/dist/lib/package-version.d.ts +19 -0
  71. package/dist/lib/package-version.d.ts.map +1 -0
  72. package/dist/lib/package-version.js +38 -0
  73. package/dist/lib/package-version.js.map +1 -0
  74. package/dist/lib/redact.d.ts +153 -0
  75. package/dist/lib/redact.d.ts.map +1 -0
  76. package/dist/lib/redact.js +207 -0
  77. package/dist/lib/redact.js.map +1 -0
  78. package/dist/lib/text.d.ts +14 -0
  79. package/dist/lib/text.d.ts.map +1 -0
  80. package/dist/lib/text.js +21 -0
  81. package/dist/lib/text.js.map +1 -0
  82. package/dist/lib/wire-shape.d.ts +131 -0
  83. package/dist/lib/wire-shape.d.ts.map +1 -0
  84. package/dist/lib/wire-shape.js +376 -0
  85. package/dist/lib/wire-shape.js.map +1 -0
  86. package/dist/onepassword.d.ts +29 -0
  87. package/dist/onepassword.d.ts.map +1 -0
  88. package/dist/onepassword.js +112 -0
  89. package/dist/onepassword.js.map +1 -0
  90. package/dist/services/_shared/transport.d.ts +148 -0
  91. package/dist/services/_shared/transport.d.ts.map +1 -0
  92. package/dist/services/_shared/transport.js +102 -0
  93. package/dist/services/_shared/transport.js.map +1 -0
  94. package/dist/services/applications/index.d.ts +210 -0
  95. package/dist/services/applications/index.d.ts.map +1 -0
  96. package/dist/services/applications/index.js +240 -0
  97. package/dist/services/applications/index.js.map +1 -0
  98. package/dist/services/availability/index.d.ts +254 -0
  99. package/dist/services/availability/index.d.ts.map +1 -0
  100. package/dist/services/availability/index.js +310 -0
  101. package/dist/services/availability/index.js.map +1 -0
  102. package/dist/services/contracts/index.d.ts +132 -0
  103. package/dist/services/contracts/index.d.ts.map +1 -0
  104. package/dist/services/contracts/index.js +211 -0
  105. package/dist/services/contracts/index.js.map +1 -0
  106. package/dist/services/engagements/index.d.ts +504 -0
  107. package/dist/services/engagements/index.d.ts.map +1 -0
  108. package/dist/services/engagements/index.js +613 -0
  109. package/dist/services/engagements/index.js.map +1 -0
  110. package/dist/services/jobs/index.d.ts +490 -0
  111. package/dist/services/jobs/index.d.ts.map +1 -0
  112. package/dist/services/jobs/index.js +753 -0
  113. package/dist/services/jobs/index.js.map +1 -0
  114. package/dist/services/payments/index.d.ts +415 -0
  115. package/dist/services/payments/index.d.ts.map +1 -0
  116. package/dist/services/payments/index.js +636 -0
  117. package/dist/services/payments/index.js.map +1 -0
  118. package/dist/services/profile/__tests__/fixtures.d.ts +214 -0
  119. package/dist/services/profile/__tests__/fixtures.d.ts.map +1 -0
  120. package/dist/services/profile/__tests__/fixtures.js +176 -0
  121. package/dist/services/profile/__tests__/fixtures.js.map +1 -0
  122. package/dist/services/profile/basic/index.d.ts +390 -0
  123. package/dist/services/profile/basic/index.d.ts.map +1 -0
  124. package/dist/services/profile/basic/index.js +1007 -0
  125. package/dist/services/profile/basic/index.js.map +1 -0
  126. package/dist/services/profile/certifications/index.d.ts +74 -0
  127. package/dist/services/profile/certifications/index.d.ts.map +1 -0
  128. package/dist/services/profile/certifications/index.js +169 -0
  129. package/dist/services/profile/certifications/index.js.map +1 -0
  130. package/dist/services/profile/education/index.d.ts +73 -0
  131. package/dist/services/profile/education/index.d.ts.map +1 -0
  132. package/dist/services/profile/education/index.js +168 -0
  133. package/dist/services/profile/education/index.js.map +1 -0
  134. package/dist/services/profile/employment/index.d.ts +111 -0
  135. package/dist/services/profile/employment/index.d.ts.map +1 -0
  136. package/dist/services/profile/employment/index.js +202 -0
  137. package/dist/services/profile/employment/index.js.map +1 -0
  138. package/dist/services/profile/external/index.d.ts +219 -0
  139. package/dist/services/profile/external/index.d.ts.map +1 -0
  140. package/dist/services/profile/external/index.js +560 -0
  141. package/dist/services/profile/external/index.js.map +1 -0
  142. package/dist/services/profile/index.d.ts +24 -0
  143. package/dist/services/profile/index.d.ts.map +1 -0
  144. package/dist/services/profile/index.js +26 -0
  145. package/dist/services/profile/index.js.map +1 -0
  146. package/dist/services/profile/industries/index.d.ts +130 -0
  147. package/dist/services/profile/industries/index.d.ts.map +1 -0
  148. package/dist/services/profile/industries/index.js +292 -0
  149. package/dist/services/profile/industries/index.js.map +1 -0
  150. package/dist/services/profile/portfolio/index.d.ts +352 -0
  151. package/dist/services/profile/portfolio/index.d.ts.map +1 -0
  152. package/dist/services/profile/portfolio/index.js +833 -0
  153. package/dist/services/profile/portfolio/index.js.map +1 -0
  154. package/dist/services/profile/resume/index.d.ts +60 -0
  155. package/dist/services/profile/resume/index.d.ts.map +1 -0
  156. package/dist/services/profile/resume/index.js +212 -0
  157. package/dist/services/profile/resume/index.js.map +1 -0
  158. package/dist/services/profile/reviews/index.d.ts +137 -0
  159. package/dist/services/profile/reviews/index.d.ts.map +1 -0
  160. package/dist/services/profile/reviews/index.js +431 -0
  161. package/dist/services/profile/reviews/index.js.map +1 -0
  162. package/dist/services/profile/shared.d.ts +127 -0
  163. package/dist/services/profile/shared.d.ts.map +1 -0
  164. package/dist/services/profile/shared.js +155 -0
  165. package/dist/services/profile/shared.js.map +1 -0
  166. package/dist/services/profile/skills/index.d.ts +212 -0
  167. package/dist/services/profile/skills/index.d.ts.map +1 -0
  168. package/dist/services/profile/skills/index.js +461 -0
  169. package/dist/services/profile/skills/index.js.map +1 -0
  170. package/dist/services/profile/visas/index.d.ts +74 -0
  171. package/dist/services/profile/visas/index.d.ts.map +1 -0
  172. package/dist/services/profile/visas/index.js +306 -0
  173. package/dist/services/profile/visas/index.js.map +1 -0
  174. package/dist/services/timesheet/index.d.ts +326 -0
  175. package/dist/services/timesheet/index.d.ts.map +1 -0
  176. package/dist/services/timesheet/index.js +324 -0
  177. package/dist/services/timesheet/index.js.map +1 -0
  178. package/dist/services/translations.d.ts +79 -0
  179. package/dist/services/translations.d.ts.map +1 -0
  180. package/dist/services/translations.js +136 -0
  181. package/dist/services/translations.js.map +1 -0
  182. package/dist/transport-resilience.d.ts +136 -0
  183. package/dist/transport-resilience.d.ts.map +1 -0
  184. package/dist/transport-resilience.js +247 -0
  185. package/dist/transport-resilience.js.map +1 -0
  186. package/dist/transport.d.ts +408 -0
  187. package/dist/transport.d.ts.map +1 -0
  188. package/dist/transport.js +691 -0
  189. package/dist/transport.js.map +1 -0
  190. package/dist/types.d.ts +41 -0
  191. package/dist/types.d.ts.map +1 -0
  192. package/dist/types.js +18 -0
  193. package/dist/types.js.map +1 -0
  194. package/package.json +40 -12
  195. package/index.js +0 -7
@@ -0,0 +1,230 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ /**
4
+ * Realistic senior-developer fixture data, deliberately fixed (no
5
+ * `new Date()` calls — every date is a hard-coded ISO 8601 string or
6
+ * integer year/month) so snapshot diffs stay deterministic across runs
7
+ * and CI hosts. IDs follow `<entity>_test_<NNN>` so a snapshot diff
8
+ * reads cleanly.
9
+ *
10
+ * No PII: every URL points at the IANA-reserved `example.com` test
11
+ * domain; every company / institution name is a fictitious placeholder
12
+ * (`Acme Financial`, `Mercury Health`, `Stellar Logistics`,
13
+ * `Test Institution`). The fixture entities don't carry email or
14
+ * person-name fields directly — those live on shapes outside this
15
+ * fixture's scope (e.g., the GraphQL `Viewer` type used by
16
+ * `services/profile/__tests__/fixtures.ts`).
17
+ *
18
+ * The persona is loosely modeled on a Toptal-eligible senior backend
19
+ * engineer — enough domain detail (TypeScript / PostgreSQL / Kubernetes
20
+ * stack, distributed-systems portfolio, Stanford CS degree, AWS
21
+ * certifications, fintech/healthtech industry tags) that table-format
22
+ * rendering tests exercise realistic column widths instead of toy data
23
+ * like `"foo"` / `"bar"`.
24
+ */
25
+ // -----------------------------------------------------------------------
26
+ // Skills
27
+ // -----------------------------------------------------------------------
28
+ // `experience` is a count of months on the wire (see `ProfileSkillSet` —
29
+ // the CLI converts a duration string like `"5y"` to months before
30
+ // calling `set()`). The trailing `// N years` comments below name the
31
+ // month count's intent so readers don't have to divide by 12.
32
+ export const SKILL_TYPESCRIPT = {
33
+ id: "sk_test_001",
34
+ experience: 96, // 8 years
35
+ rating: "EXPERT",
36
+ public: true,
37
+ position: 1,
38
+ skill: { id: "skill_cat_ts", name: "TypeScript" },
39
+ connectionsCount: 4,
40
+ };
41
+ export const SKILL_POSTGRES = {
42
+ id: "sk_test_002",
43
+ experience: 84, // 7 years
44
+ rating: "EXPERT",
45
+ public: true,
46
+ position: 2,
47
+ skill: { id: "skill_cat_pg", name: "PostgreSQL" },
48
+ connectionsCount: 3,
49
+ };
50
+ export const SKILL_KUBERNETES = {
51
+ id: "sk_test_003",
52
+ experience: 48, // 4 years
53
+ rating: "STRONG",
54
+ public: true,
55
+ position: 3,
56
+ skill: { id: "skill_cat_k8s", name: "Kubernetes" },
57
+ connectionsCount: 2,
58
+ };
59
+ export const SKILL_GRAPHQL = {
60
+ id: "sk_test_004",
61
+ experience: 60, // 5 years
62
+ rating: "STRONG",
63
+ public: true,
64
+ position: 4,
65
+ skill: { id: "skill_cat_gql", name: "GraphQL" },
66
+ connectionsCount: 2,
67
+ };
68
+ // -----------------------------------------------------------------------
69
+ // Portfolio — paragraph-bearing entities (description + accomplishment)
70
+ // -----------------------------------------------------------------------
71
+ export const PORTFOLIO_DISTRIBUTED_LEDGER = {
72
+ id: "port_test_001",
73
+ title: "Distributed transaction ledger",
74
+ description: "Designed and shipped a multi-region transaction ledger handling 12k writes/sec at p99 latency under 35ms. " +
75
+ "Built on PostgreSQL logical replication with a custom conflict-resolution layer and an audit trail wired " +
76
+ "into Kafka. Stack: TypeScript, Node 20, PostgreSQL 15, Kafka, Kubernetes on AWS EKS.",
77
+ link: "https://example.com/case-studies/ledger",
78
+ highlight: true,
79
+ coverImage: "https://example.com/covers/ledger.png",
80
+ accomplishment: "Cut reconciliation lead time from 18 hours to under 4 minutes; eliminated a recurring weekend on-call class.",
81
+ publicationPermit: true,
82
+ clientOrCompanyName: "Acme Financial",
83
+ websiteUrl: "https://example.com/acme",
84
+ toptalRelated: true,
85
+ showViaToptal: true,
86
+ kind: "classic",
87
+ skills: [{ id: "sk_test_typescript", name: "TypeScript" }],
88
+ industries: [{ id: "ind_test_finance", name: "Financial Software" }],
89
+ };
90
+ export const PORTFOLIO_EHR_GATEWAY = {
91
+ id: "port_test_002",
92
+ title: "FHIR-compliant EHR gateway",
93
+ description: "Built a HIPAA-compliant gateway exposing a subset of FHIR R4 resources to third-party clinical apps. " +
94
+ "Authentication via SMART-on-FHIR (OAuth 2 + OIDC); per-resource consent enforcement at the API gateway. " +
95
+ "Operated 99.97% uptime over 14 months across three AWS regions.",
96
+ link: "https://example.com/case-studies/fhir-gateway",
97
+ highlight: true,
98
+ coverImage: null,
99
+ accomplishment: "Onboarded 11 partner clinics in the first quarter; passed an external HIPAA audit on first attempt.",
100
+ publicationPermit: true,
101
+ clientOrCompanyName: "Mercury Health",
102
+ websiteUrl: "https://example.com/mercury",
103
+ toptalRelated: false,
104
+ showViaToptal: true,
105
+ kind: "code_base",
106
+ skills: [{ id: "sk_test_typescript", name: "TypeScript" }],
107
+ industries: [{ id: "ind_test_healthcare", name: "Healthcare Software" }],
108
+ };
109
+ export const PORTFOLIO_OBSERVABILITY = {
110
+ id: "port_test_003",
111
+ title: "Internal observability platform",
112
+ description: "Replaced a legacy logging stack with an OpenTelemetry-native observability platform for a 200-engineer org. " +
113
+ "Unified logs, metrics, and traces under a single retention policy; reduced infra spend by 38% while " +
114
+ "doubling cardinality.",
115
+ link: "https://example.com/case-studies/observability",
116
+ highlight: false,
117
+ coverImage: null,
118
+ accomplishment: "MTTR for production incidents dropped from 47 minutes to 11 minutes within two quarters of rollout.",
119
+ publicationPermit: true,
120
+ clientOrCompanyName: "Stellar Logistics",
121
+ websiteUrl: null,
122
+ toptalRelated: false,
123
+ showViaToptal: false,
124
+ kind: "basic",
125
+ skills: [{ id: "sk_test_typescript", name: "TypeScript" }],
126
+ industries: [{ id: "ind_test_software", name: "Software" }],
127
+ };
128
+ // -----------------------------------------------------------------------
129
+ // Employment — paragraph-bearing experienceItems
130
+ // -----------------------------------------------------------------------
131
+ export const EMPLOYMENT_PRINCIPAL_ENGINEER = {
132
+ id: "emp_test_001",
133
+ company: "Acme Financial",
134
+ position: "Principal Engineer",
135
+ companyWebsite: "https://example.com/acme",
136
+ noWebsite: false,
137
+ startDate: 2021,
138
+ endDate: null, // current role
139
+ experienceItems: [
140
+ "Owned the architecture of the multi-region transaction ledger from prototype to production at 12k writes/sec.",
141
+ "Mentored a team of 6 engineers; ran weekly architecture-review forums and pairing sessions on hard-to-debug latency tails.",
142
+ "Drove the migration off a hand-rolled ORM onto Drizzle, removing ~14k lines of bespoke SQL plumbing.",
143
+ ],
144
+ highlight: true,
145
+ showViaToptal: true,
146
+ toptalRelated: false,
147
+ };
148
+ export const EMPLOYMENT_SENIOR_ENGINEER = {
149
+ id: "emp_test_002",
150
+ company: "Mercury Health",
151
+ position: "Senior Software Engineer",
152
+ companyWebsite: "https://example.com/mercury",
153
+ noWebsite: false,
154
+ startDate: 2017,
155
+ endDate: 2021,
156
+ experienceItems: [
157
+ "Built the FHIR-compliant EHR gateway from green field to 11 partner clinics in production.",
158
+ "Led the SMART-on-FHIR auth integration; co-authored an internal RFC adopted across two sister product teams.",
159
+ ],
160
+ highlight: true,
161
+ showViaToptal: true,
162
+ toptalRelated: false,
163
+ };
164
+ // -----------------------------------------------------------------------
165
+ // Education
166
+ // -----------------------------------------------------------------------
167
+ export const EDUCATION_STANFORD_BS = {
168
+ id: "edu_test_001",
169
+ institution: "Stanford University",
170
+ degree: "Bachelor of Science",
171
+ fieldOfStudy: "Computer Science",
172
+ location: "Stanford, CA",
173
+ title: "BS, Computer Science",
174
+ yearFrom: 2010,
175
+ yearTo: 2014,
176
+ highlight: true,
177
+ };
178
+ // -----------------------------------------------------------------------
179
+ // Certifications
180
+ // -----------------------------------------------------------------------
181
+ export const CERT_AWS_PRO = {
182
+ id: "cert_test_001",
183
+ certificate: "AWS Certified Solutions Architect — Professional",
184
+ institution: "Amazon Web Services",
185
+ link: "https://example.com/cert/aws-pro",
186
+ number: "AWS-SAP-12345",
187
+ validFromMonth: 3,
188
+ validFromYear: 2023,
189
+ validToMonth: 3,
190
+ validToYear: 2026,
191
+ highlight: true,
192
+ };
193
+ export const CERT_CKAD = {
194
+ id: "cert_test_002",
195
+ certificate: "Certified Kubernetes Application Developer",
196
+ institution: "Cloud Native Computing Foundation",
197
+ link: "https://example.com/cert/ckad",
198
+ number: "CKAD-67890",
199
+ validFromMonth: 6,
200
+ validFromYear: 2022,
201
+ validToMonth: 6,
202
+ validToYear: 2025,
203
+ highlight: false,
204
+ };
205
+ // -----------------------------------------------------------------------
206
+ // Industries
207
+ // -----------------------------------------------------------------------
208
+ export const INDUSTRY_FINTECH = {
209
+ id: "ind_test_001",
210
+ title: "Financial services",
211
+ about: "8 years building ledger, payments, and reconciliation systems for B2B fintech.",
212
+ domainArea: "Payments and ledger",
213
+ };
214
+ export const INDUSTRY_HEALTHTECH = {
215
+ id: "ind_test_002",
216
+ title: "Healthcare",
217
+ about: "4 years on HIPAA-compliant clinical-data infrastructure and FHIR integrations.",
218
+ domainArea: "Clinical data exchange",
219
+ };
220
+ // -----------------------------------------------------------------------
221
+ // Travel visas
222
+ // -----------------------------------------------------------------------
223
+ export const VISA_US = {
224
+ id: "visa_test_001",
225
+ countryId: "country_us",
226
+ countryName: "United States",
227
+ visaType: "B1/B2",
228
+ expiryDate: "2030-06-15",
229
+ };
230
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/profile/data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Profile rendering fixtures — reusable test data for empty / single-item
3
+ * / paragraph-bearing / full / minimal list scenarios. See `README.md`
4
+ * for the full builder API and the rationale behind the
5
+ * `buildParagraphBearingList` shape.
6
+ */
7
+ export { buildEmptyProfile, buildFullProfile, buildMinimalProfile, buildParagraphBearingList, buildSingleItemList, } from "./builders.js";
8
+ export type { Certification, Education, Employment, IndustryProfile, PortfolioItem, ProfileFixture, ProfileSkillSet, TravelVisa, } from "./types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/profile/index.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,EACf,UAAU,GACX,MAAM,YAAY,CAAC"}
@@ -0,0 +1,10 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ /**
4
+ * Profile rendering fixtures — reusable test data for empty / single-item
5
+ * / paragraph-bearing / full / minimal list scenarios. See `README.md`
6
+ * for the full builder API and the rationale behind the
7
+ * `buildParagraphBearingList` shape.
8
+ */
9
+ export { buildEmptyProfile, buildFullProfile, buildMinimalProfile, buildParagraphBearingList, buildSingleItemList, } from "./builders.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/profile/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC;;;;;GAKG;AAEH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { Certification } from "../../../services/profile/certifications/index.js";
2
+ import type { Education } from "../../../services/profile/education/index.js";
3
+ import type { Employment } from "../../../services/profile/employment/index.js";
4
+ import type { IndustryProfile } from "../../../services/profile/industries/index.js";
5
+ import type { PortfolioItem } from "../../../services/profile/portfolio/index.js";
6
+ import type { ProfileSkillSet } from "../../../services/profile/skills/index.js";
7
+ import type { TravelVisa } from "../../../services/profile/visas/index.js";
8
+ /**
9
+ * Fixture-only aggregate bundling every per-domain list a CLI/MCP rendering
10
+ * test might want to drive against in one shape. Production code does not
11
+ * have an aggregate `Profile` — each sub-domain (`profile.skills`,
12
+ * `profile.portfolio`, …) returns its own list — so this aggregate exists
13
+ * solely so test code can write
14
+ *
15
+ * ```ts
16
+ * const fx = buildEmptyProfile();
17
+ * expect(fx.skills).toEqual([]);
18
+ * expect(fx.portfolio).toEqual([]);
19
+ * ```
20
+ *
21
+ * Each member is the production entity type verbatim (re-exported from the
22
+ * sub-domain modules — no type duplication, no hand-rolled mock shapes).
23
+ *
24
+ * Note: the issue body referenced a `reviews` list with paragraph-bearing
25
+ * body text, but the production `reviews` domain (`profile.reviews`) is the
26
+ * admin section-review queue (`SectionReview`) with no prose body. The
27
+ * paragraph-bearing fixture therefore populates `portfolio` items with
28
+ * realistic multi-sentence `description` + `accomplishment` content (the
29
+ * actual paragraph-bearing fields in production). See the `README.md`
30
+ * sibling for the rationale.
31
+ */
32
+ export interface ProfileFixture {
33
+ skills: ProfileSkillSet[];
34
+ portfolio: PortfolioItem[];
35
+ employment: Employment[];
36
+ education: Education[];
37
+ certifications: Certification[];
38
+ industries: IndustryProfile[];
39
+ visas: TravelVisa[];
40
+ }
41
+ /**
42
+ * Re-exports of the per-domain entity types so consumers can pull
43
+ * everything they need from one fixture-module path:
44
+ *
45
+ * ```ts
46
+ * import type { ProfileFixture, ProfileSkillSet } from "../fixtures/profile";
47
+ * ```
48
+ *
49
+ * The re-exports point at the production types — there is no
50
+ * fixture-private variant.
51
+ */
52
+ export type { Certification, Education, Employment, IndustryProfile, PortfolioItem, ProfileSkillSet, TravelVisa };
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/profile/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/__tests__/fixtures/profile/types.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Cross-cutting typed-error contract for authentication failures.
3
+ *
4
+ * Each Toptal Talent backend (gateway, talent_profile, scheduler) reports
5
+ * authentication failures with a different wire shape:
6
+ *
7
+ * - gateway → JSON `{ errors: [{ extensions: { code: 'AUTHENTICATION_REQUIRED' } }] }`
8
+ * - talent_profile → JSON `{ errors: [{ extensions: { code: 'UNAUTHENTICATED' } }] }`
9
+ * OR HTML Cloudflare challenge (HTTP 403)
10
+ * - scheduler → JSON `{ error: 'unauthorized' }` (post-v1)
11
+ *
12
+ * Transport and service modules detect each shape and throw a concrete
13
+ * `TtctlError` subclass. Errors are NOT caught at the service layer — they
14
+ * propagate to `@ttctl/cli` (CLI) and `@ttctl/mcp` (MCP) which present them
15
+ * per surface conventions (CLI: human-readable text + exit code; MCP:
16
+ * structured tool-error response).
17
+ *
18
+ * Each subclass carries:
19
+ * - `code` — stable machine-readable identifier (e.g. `'AUTH_REVOKED'`).
20
+ * Script consumers branch on this without parsing prose.
21
+ * - `recovery` — short, actionable user-facing string explaining how to
22
+ * recover. Phrasing should match what the user CAN do, not
23
+ * what TTCtl COULD do internally.
24
+ * - `autoRecover` (optional) — when `true`, signals that the transport or
25
+ * service layer SHOULD attempt recovery once before
26
+ * surfacing the error (e.g. scheduler-bearer re-mint via
27
+ * `GetTopSchedulerToken` post-v1). Defaults to `false`.
28
+ *
29
+ * See `hq/engineering/adr/ADR-005-auth-model.md` for the cross-surface
30
+ * auth model. See issue #77 for the full failure-mode table.
31
+ */
32
+ export declare abstract class TtctlError extends Error {
33
+ /**
34
+ * Stable, machine-readable error code. Subclasses provide a literal string
35
+ * (e.g. `'AUTH_REVOKED'`, `'CF_403_CLEARANCE'`). Script consumers branch
36
+ * on this; the value is part of the public API and should not change
37
+ * casually.
38
+ */
39
+ abstract readonly code: string;
40
+ /**
41
+ * Short, actionable user-facing string. Phrased imperatively where the
42
+ * user can take an action (e.g. `Run \`ttctl auth signin\` to
43
+ * re-authenticate.`). Phrased descriptively where there is no clean user
44
+ * action (e.g. `Cloudflare's bot-management has flipped a feature flag.
45
+ * File an issue at ...`). Surface-renderers (CLI / MCP) pass this through
46
+ * verbatim.
47
+ */
48
+ abstract readonly recovery: string;
49
+ /**
50
+ * When `true`, the transport or service layer should attempt automated
51
+ * recovery once before surfacing this error to the user. Concrete
52
+ * subclasses opt in by overriding to `true` (e.g. `SchedulerBearerExpired`
53
+ * post-v1, where `GetTopSchedulerToken` re-mints transparently).
54
+ *
55
+ * Default `false` — most auth failures (revoked token, Cloudflare block)
56
+ * require user intervention and cannot be auto-recovered.
57
+ */
58
+ readonly autoRecover: boolean;
59
+ }
60
+ /**
61
+ * Authentication revoked or expired — the token TTCtl is replaying as
62
+ * `Authorization: Token token=<X>` is no longer accepted by the gateway.
63
+ *
64
+ * Detected at the service layer when:
65
+ * - HTTP response is 401, OR
66
+ * - GraphQL response carries `errors[0].extensions.code` equal to
67
+ * `'AUTHENTICATION_REQUIRED'` (gateway form) or `'UNAUTHENTICATED'`
68
+ * (talent_profile form).
69
+ *
70
+ * Recovery is unambiguous: the user runs `ttctl auth signin` to re-mint a
71
+ * session token. There is no automated path — sign-in requires credentials
72
+ * the agent does not have.
73
+ */
74
+ export declare class AuthRevokedError extends TtctlError {
75
+ readonly name = "AuthRevokedError";
76
+ readonly code = "AUTH_REVOKED";
77
+ readonly recovery = "Run `ttctl auth signin` to re-authenticate.";
78
+ constructor(message?: string, options?: {
79
+ cause?: unknown;
80
+ });
81
+ }
82
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,8BAAsB,UAAW,SAAQ,KAAK;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAEnC;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAS;CACvC;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAC9C,SAAkB,IAAI,sBAAsB;IAC5C,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,QAAQ,iDAAiD;gBAEtD,OAAO,GAAE,MAAyC,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAG9F"}
@@ -0,0 +1,68 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ /**
4
+ * Cross-cutting typed-error contract for authentication failures.
5
+ *
6
+ * Each Toptal Talent backend (gateway, talent_profile, scheduler) reports
7
+ * authentication failures with a different wire shape:
8
+ *
9
+ * - gateway → JSON `{ errors: [{ extensions: { code: 'AUTHENTICATION_REQUIRED' } }] }`
10
+ * - talent_profile → JSON `{ errors: [{ extensions: { code: 'UNAUTHENTICATED' } }] }`
11
+ * OR HTML Cloudflare challenge (HTTP 403)
12
+ * - scheduler → JSON `{ error: 'unauthorized' }` (post-v1)
13
+ *
14
+ * Transport and service modules detect each shape and throw a concrete
15
+ * `TtctlError` subclass. Errors are NOT caught at the service layer — they
16
+ * propagate to `@ttctl/cli` (CLI) and `@ttctl/mcp` (MCP) which present them
17
+ * per surface conventions (CLI: human-readable text + exit code; MCP:
18
+ * structured tool-error response).
19
+ *
20
+ * Each subclass carries:
21
+ * - `code` — stable machine-readable identifier (e.g. `'AUTH_REVOKED'`).
22
+ * Script consumers branch on this without parsing prose.
23
+ * - `recovery` — short, actionable user-facing string explaining how to
24
+ * recover. Phrasing should match what the user CAN do, not
25
+ * what TTCtl COULD do internally.
26
+ * - `autoRecover` (optional) — when `true`, signals that the transport or
27
+ * service layer SHOULD attempt recovery once before
28
+ * surfacing the error (e.g. scheduler-bearer re-mint via
29
+ * `GetTopSchedulerToken` post-v1). Defaults to `false`.
30
+ *
31
+ * See `hq/engineering/adr/ADR-005-auth-model.md` for the cross-surface
32
+ * auth model. See issue #77 for the full failure-mode table.
33
+ */
34
+ export class TtctlError extends Error {
35
+ /**
36
+ * When `true`, the transport or service layer should attempt automated
37
+ * recovery once before surfacing this error to the user. Concrete
38
+ * subclasses opt in by overriding to `true` (e.g. `SchedulerBearerExpired`
39
+ * post-v1, where `GetTopSchedulerToken` re-mints transparently).
40
+ *
41
+ * Default `false` — most auth failures (revoked token, Cloudflare block)
42
+ * require user intervention and cannot be auto-recovered.
43
+ */
44
+ autoRecover = false;
45
+ }
46
+ /**
47
+ * Authentication revoked or expired — the token TTCtl is replaying as
48
+ * `Authorization: Token token=<X>` is no longer accepted by the gateway.
49
+ *
50
+ * Detected at the service layer when:
51
+ * - HTTP response is 401, OR
52
+ * - GraphQL response carries `errors[0].extensions.code` equal to
53
+ * `'AUTHENTICATION_REQUIRED'` (gateway form) or `'UNAUTHENTICATED'`
54
+ * (talent_profile form).
55
+ *
56
+ * Recovery is unambiguous: the user runs `ttctl auth signin` to re-mint a
57
+ * session token. There is no automated path — sign-in requires credentials
58
+ * the agent does not have.
59
+ */
60
+ export class AuthRevokedError extends TtctlError {
61
+ name = "AuthRevokedError";
62
+ code = "AUTH_REVOKED";
63
+ recovery = "Run `ttctl auth signin` to re-authenticate.";
64
+ constructor(message = "Session is invalid or expired.", options) {
65
+ super(message, options);
66
+ }
67
+ }
68
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,OAAgB,UAAW,SAAQ,KAAK;IAmB5C;;;;;;;;OAQG;IACM,WAAW,GAAY,KAAK,CAAC;CACvC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC5B,IAAI,GAAG,kBAAkB,CAAC;IACnC,IAAI,GAAG,cAAc,CAAC;IACtB,QAAQ,GAAG,6CAA6C,CAAC;IAElE,YAAY,UAAkB,gCAAgC,EAAE,OAA6B;QAC3F,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF"}