@ttctl/core 0.1.0-rc.7 → 0.1.0-rc.8
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/dist/__generated__/gateway.d.ts +9 -9
- package/dist/__generated__/gateway.d.ts.map +1 -1
- package/dist/__generated__/zod-schemas.d.ts +9 -9
- package/dist/__generated__/zod-schemas.d.ts.map +1 -1
- package/dist/__generated__/zod-schemas.js +9 -9
- package/dist/__generated__/zod-schemas.js.map +1 -1
- package/dist/__tests__/fixtures/profile/builders.d.ts.map +1 -1
- package/dist/__tests__/fixtures/profile/builders.js +1 -0
- package/dist/__tests__/fixtures/profile/builders.js.map +1 -1
- package/dist/__tests__/fixtures/profile/data.d.ts.map +1 -1
- package/dist/__tests__/fixtures/profile/data.js +2 -0
- package/dist/__tests__/fixtures/profile/data.js.map +1 -1
- package/dist/consent.d.ts +236 -0
- package/dist/consent.d.ts.map +1 -0
- package/dist/consent.js +225 -0
- package/dist/consent.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/services/applications/index.d.ts +917 -13
- package/dist/services/applications/index.d.ts.map +1 -1
- package/dist/services/applications/index.js +1284 -6
- package/dist/services/applications/index.js.map +1 -1
- package/dist/services/jobs/index.d.ts.map +1 -1
- package/dist/services/jobs/index.js.map +1 -1
- package/dist/services/payments/index.d.ts +66 -0
- package/dist/services/payments/index.d.ts.map +1 -1
- package/dist/services/payments/index.js +120 -0
- package/dist/services/payments/index.js.map +1 -1
- package/dist/services/profile/employment/index.d.ts +50 -4
- package/dist/services/profile/employment/index.d.ts.map +1 -1
- package/dist/services/profile/employment/index.js +73 -16
- package/dist/services/profile/employment/index.js.map +1 -1
- package/dist/services/profile/reviews/index.d.ts +31 -1
- package/dist/services/profile/reviews/index.d.ts.map +1 -1
- package/dist/services/profile/reviews/index.js +19 -1
- package/dist/services/profile/reviews/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import type { JobExpertiseAnswerInput, JobPositionAnswerInput, PitchInput } from "../../__generated__/zod-schemas.js";
|
|
2
|
+
import { JobExpertiseAnswerInputSchema, JobPositionAnswerInputSchema, PitchInputSchema } from "../../__generated__/zod-schemas.js";
|
|
1
3
|
import type { DryRunPreview } from "../../transport.js";
|
|
4
|
+
export type { JobExpertiseAnswerInput, JobPositionAnswerInput, PitchInput };
|
|
5
|
+
export { JobExpertiseAnswerInputSchema, JobPositionAnswerInputSchema, PitchInputSchema };
|
|
2
6
|
/**
|
|
3
7
|
* Applications-domain error codes. Mirrors the `ProfileError` /
|
|
4
8
|
* `SkillsError` shape per project convention so each sub-domain carries
|
|
@@ -14,7 +18,25 @@ import type { DryRunPreview } from "../../transport.js";
|
|
|
14
18
|
* `NOT_FOUND` so the CLI can render a "no such application" line and
|
|
15
19
|
* the MCP tool can return a structured `(NOT_FOUND)` error response.
|
|
16
20
|
*/
|
|
17
|
-
export type ApplicationsErrorCode = "NO_VIEWER" | "NOT_FOUND" | "GRAPHQL_ERROR" | "MUTATION_ERROR" | "NETWORK_ERROR" | "WIRE_SHAPE_ERROR"
|
|
21
|
+
export type ApplicationsErrorCode = "NO_VIEWER" | "NOT_FOUND" | "GRAPHQL_ERROR" | "MUTATION_ERROR" | "NETWORK_ERROR" | "WIRE_SHAPE_ERROR"
|
|
22
|
+
/**
|
|
23
|
+
* Direct-apply consent gate (#426). The wire's `consentIssued: Boolean!`
|
|
24
|
+
* is a legal-compliance attestation; the service refuses to issue the
|
|
25
|
+
* mutation unless the caller explicitly passes `consentIssued: true`
|
|
26
|
+
* on {@link ApplyInput}. Same posture #411 took on the DESTRUCTIVE
|
|
27
|
+
* IR mutations, with the legal dimension added. Fired before any wire
|
|
28
|
+
* call.
|
|
29
|
+
*/
|
|
30
|
+
| "CONSENT_REQUIRED"
|
|
31
|
+
/**
|
|
32
|
+
* Direct-apply double-application gate (#426). The wire returns
|
|
33
|
+
* `success: false` with `errors[].key === "already_applied"` when the
|
|
34
|
+
* talent has previously applied to the same job. Mapped to a typed
|
|
35
|
+
* code so callers (CLI / MCP / agents) can surface a "you already
|
|
36
|
+
* applied" hint pointing at `ttctl applications show <activity-id>`
|
|
37
|
+
* instead of the generic `MUTATION_ERROR` envelope.
|
|
38
|
+
*/
|
|
39
|
+
| "ALREADY_APPLIED" | "UNKNOWN";
|
|
18
40
|
export declare class ApplicationsError extends Error {
|
|
19
41
|
readonly code: ApplicationsErrorCode;
|
|
20
42
|
readonly name = "ApplicationsError";
|
|
@@ -260,13 +282,17 @@ export interface AvailabilityRequestRespondPayload {
|
|
|
260
282
|
* {@link AvailabilityRequestKind} for the value spellings.
|
|
261
283
|
* - `comment` (optional) — the talent's free-text accompanying message.
|
|
262
284
|
* Mapped to the wire's `talentComment` field.
|
|
263
|
-
* - `matcherQuestionsAnswers`, `expertiseQuestionsAnswers`, `
|
|
285
|
+
* - `matcherQuestionsAnswers`, `expertiseQuestionsAnswers`, `pitchInput`
|
|
264
286
|
* (optional) — structural inputs for AR confirmations that require
|
|
265
|
-
* matcher / expertise question answers or a custom pitch.
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
* `
|
|
287
|
+
* matcher / expertise question answers or a custom pitch. Stage-2
|
|
288
|
+
* (#438) types these against the recovered SDL shapes —
|
|
289
|
+
* {@link JobPositionAnswerInput}, {@link JobExpertiseAnswerInput},
|
|
290
|
+
* {@link PitchInput} (regenerated from #425's recovery output).
|
|
291
|
+
* `matcherQuestionsAnswers` entries use `id` (NOT `questionId`) per
|
|
292
|
+
* the SDL; `expertiseQuestionsAnswers` entries use `questionId`.
|
|
293
|
+
* The service still passes them through to the wire opaquely; the
|
|
294
|
+
* typing is the boundary contract for CLI / MCP / direct-Core
|
|
295
|
+
* callers.
|
|
270
296
|
*/
|
|
271
297
|
export interface ConfirmInput {
|
|
272
298
|
/** Optional talent-side free-text message. Wire field: `talentComment`. */
|
|
@@ -275,12 +301,12 @@ export interface ConfirmInput {
|
|
|
275
301
|
requestedHourlyRate?: string;
|
|
276
302
|
/** AR kind. Auto-detected from `metadata.__typename` when omitted. INFERRED enum values — see {@link AvailabilityRequestKind}. */
|
|
277
303
|
kind?: AvailabilityRequestKind;
|
|
278
|
-
/** Optional matcher-questions answers
|
|
279
|
-
matcherQuestionsAnswers?:
|
|
280
|
-
/** Optional expertise-questions answers
|
|
281
|
-
expertiseQuestionsAnswers?:
|
|
282
|
-
/** Optional pitch input
|
|
283
|
-
pitchInput?:
|
|
304
|
+
/** Optional matcher-questions answers — wire shape `JobPositionAnswerInput[]` (`{ id, answer }`). */
|
|
305
|
+
matcherQuestionsAnswers?: JobPositionAnswerInput[];
|
|
306
|
+
/** Optional expertise-questions answers — wire shape `JobExpertiseAnswerInput[]` (`{ questionId, other, subjectId }`). */
|
|
307
|
+
expertiseQuestionsAnswers?: JobExpertiseAnswerInput[];
|
|
308
|
+
/** Optional pitch input — wire shape `PitchInput`. */
|
|
309
|
+
pitchInput?: PitchInput;
|
|
284
310
|
}
|
|
285
311
|
/**
|
|
286
312
|
* Input for {@link reject}. The wire mutation's input takes
|
|
@@ -473,6 +499,259 @@ export declare function show(token: string, id: string): Promise<JobActivityItem
|
|
|
473
499
|
* user knows exactly what went wrong.
|
|
474
500
|
*/
|
|
475
501
|
export declare function stats(token: string): Promise<ApplicationsStats>;
|
|
502
|
+
/**
|
|
503
|
+
* One entry of `viewer.job.operations.apply.errors` (#424). Schema
|
|
504
|
+
* declares both fields as `String!` — non-null — but the projection
|
|
505
|
+
* helper {@link projectApplyErrors} keeps a defensive list-entry null
|
|
506
|
+
* filter because the WIRE shape on the schema-gap path (this op is in
|
|
507
|
+
* `GATEWAY_MOBILE_KNOWN_UNTRUSTED_OPS`) is best-effort.
|
|
508
|
+
*/
|
|
509
|
+
export interface ApplyError {
|
|
510
|
+
code: string;
|
|
511
|
+
message: string;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Aggregate pre-apply context returned by {@link applyData} (#424).
|
|
515
|
+
*
|
|
516
|
+
* Surfaces the load-bearing scalars from the captured `JobApplyData`
|
|
517
|
+
* operation — the suggested rate (REQ-A4), platform validation
|
|
518
|
+
* bounds, the apply-state errors, and basic job context — trimmed of
|
|
519
|
+
* the heavy pitch / talent-card / market-condition cascades the
|
|
520
|
+
* captured op also pulls in. Downstream consumers:
|
|
521
|
+
*
|
|
522
|
+
* - **#426 (apply core fn)** — reads `canApply` to short-circuit
|
|
523
|
+
* before the mutation, uses `suggestedRate` as the
|
|
524
|
+
* `requestedHourlyRate` default, validates against `rateValidation`.
|
|
525
|
+
* - **#437 (`jobs show`)** — surfaces `applyErrors` so the user can
|
|
526
|
+
* see WHY they can't apply (already applied, job closed, etc.)
|
|
527
|
+
* directly on the job-detail view.
|
|
528
|
+
*
|
|
529
|
+
* `canApply` is a convenience boolean derived from
|
|
530
|
+
* `applyErrors.length === 0` — kept as a separate field so callers
|
|
531
|
+
* don't have to recompute it.
|
|
532
|
+
*/
|
|
533
|
+
export interface PreApplyData {
|
|
534
|
+
job: {
|
|
535
|
+
id: string;
|
|
536
|
+
isCoaching: boolean | null;
|
|
537
|
+
hasRequiredApplicationPitch: boolean | null;
|
|
538
|
+
};
|
|
539
|
+
/** Empty when the talent may apply; populated lists the blocking reasons. */
|
|
540
|
+
applyErrors: ApplyError[];
|
|
541
|
+
/** Convenience: `true` iff `applyErrors` is empty. */
|
|
542
|
+
canApply: boolean;
|
|
543
|
+
/**
|
|
544
|
+
* Talent's configured hourly rate (`viewerRole.rates.hourly`). The
|
|
545
|
+
* apply path uses this as the `requestedHourlyRate` default
|
|
546
|
+
* (REQ-A4). `null` when the viewerRole is absent (defensive — the
|
|
547
|
+
* schema declares `ViewerRole.rates.hourly: String!`, but absence
|
|
548
|
+
* is treated as null projection rather than a hard error).
|
|
549
|
+
*/
|
|
550
|
+
suggestedRate: string | null;
|
|
551
|
+
/**
|
|
552
|
+
* Platform hourly-rate validation bounds. `null` when the platform
|
|
553
|
+
* configuration block is absent (defensive — the schema declares
|
|
554
|
+
* `PlatformConfiguration.rateValidationRules: TalentRateValidationRules!`
|
|
555
|
+
* non-null, but gateway-side absence is surfaced as null projection
|
|
556
|
+
* rather than a hard error). Note `rateStep` is `Int` on the wire,
|
|
557
|
+
* not a decimal string.
|
|
558
|
+
*/
|
|
559
|
+
rateValidation: {
|
|
560
|
+
minRate: string;
|
|
561
|
+
rateStep: number;
|
|
562
|
+
} | null;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* One question on the apply form (#424). The four-field shape is
|
|
566
|
+
* uniform across matcher and expertise variants per REQ-Q1:
|
|
567
|
+
*
|
|
568
|
+
* - `identifier` — the wire `id` field (`JobPositionQuestion.id` /
|
|
569
|
+
* `JobExpertiseQuestion.id`). Threaded into the apply-mutation
|
|
570
|
+
* answer arrays at asymmetric field names per the recovered SDL:
|
|
571
|
+
* `JobPositionAnswerInput.id` (matcher) and
|
|
572
|
+
* `JobExpertiseAnswerInput.questionId` (expertise). Both reference
|
|
573
|
+
* this same `identifier`; see ADR-008 § Decision Part 2 and #438
|
|
574
|
+
* for the recovered-shape rationale.
|
|
575
|
+
* - `prompt` — the human-readable question text. For matcher
|
|
576
|
+
* questions: the wire `question` field. For expertise questions:
|
|
577
|
+
* the `subject.name` (`Industry.name` or `Skill.name`) — expertise
|
|
578
|
+
* questions ask "which of your profile items demonstrates this
|
|
579
|
+
* skill / industry?", so the subject's name IS the prompt the
|
|
580
|
+
* user sees.
|
|
581
|
+
* - `type` — TTCtl-side discriminant `"matcher" | "expertise"`,
|
|
582
|
+
* making each question self-describing if consumers flatten the
|
|
583
|
+
* two arrays (e.g., #426's answers-file template builder).
|
|
584
|
+
* - `isMandatory` — for matcher questions, the wire `isRequired`
|
|
585
|
+
* field. For expertise questions: projected as `true`. The
|
|
586
|
+
* captured `JobApplicationQuestions` operation selects no
|
|
587
|
+
* per-question mandatory flag on `expertiseQuestions` (and the
|
|
588
|
+
* synthesized schema doesn't even declare `JobExpertiseQuestion`),
|
|
589
|
+
* but the `JobApply` mutation takes
|
|
590
|
+
* `$expertiseQuestionsAnswers: [JobExpertiseAnswerInput!]` as a
|
|
591
|
+
* required apply-payload field (research note
|
|
592
|
+
* `03-applications.md` § Apply flow specifics: "Both question
|
|
593
|
+
* types ... must be fetched first ... The client cannot guess
|
|
594
|
+
* them"). Documented inference; #445 live E2E is the wire
|
|
595
|
+
* authority and may refine this projection if real data surfaces
|
|
596
|
+
* a more nuanced mandatory-ness signal.
|
|
597
|
+
*/
|
|
598
|
+
export interface ApplicationQuestion {
|
|
599
|
+
identifier: string;
|
|
600
|
+
prompt: string;
|
|
601
|
+
type: "matcher" | "expertise";
|
|
602
|
+
isMandatory: boolean;
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Questions inventory returned by {@link applyQuestions} (#424).
|
|
606
|
+
* Mirrors the captured `JobApplicationQuestions` operation's two
|
|
607
|
+
* parallel selections — `viewer.job.questions(hideExpertiseQuestion:
|
|
608
|
+
* true)` for matcher questions, `viewer.job.expertiseQuestions` for
|
|
609
|
+
* expertise — projecting each entry to the four-field
|
|
610
|
+
* {@link ApplicationQuestion} shape. Empty arrays surface verbatim
|
|
611
|
+
* when the job has no questions of that kind.
|
|
612
|
+
*/
|
|
613
|
+
export interface ApplicationQuestions {
|
|
614
|
+
matcherQuestions: ApplicationQuestion[];
|
|
615
|
+
expertiseQuestions: ApplicationQuestion[];
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Rate insight when the talent's rate (or default rate) is judged
|
|
619
|
+
* COMPETITIVE relative to the job's market (#424). Discriminated-union
|
|
620
|
+
* member of {@link RateInsight}; surfaces the captured wire's
|
|
621
|
+
* `TalentJobRateInsightCompetitive` fields verbatim.
|
|
622
|
+
*
|
|
623
|
+
* All revenue / rate fields are `BigDecimal` decimal-string scalars
|
|
624
|
+
* per the captured wire (the captured
|
|
625
|
+
* `JobApplicationRateInsight.graphql` operation selects them bare,
|
|
626
|
+
* no `{ }` sub-selection; the synthesized schema confirms
|
|
627
|
+
* `BigDecimal`). They are NOT a `Money { decimal verbose }` shape —
|
|
628
|
+
* see PR body for the deviation from the issue parenthetical.
|
|
629
|
+
*/
|
|
630
|
+
export interface CompetitiveRateInsight {
|
|
631
|
+
kind: "competitive";
|
|
632
|
+
/** Estimated revenue at the supplied rate (BigDecimal scalar). */
|
|
633
|
+
estimatedRevenue: string | null;
|
|
634
|
+
/** Server-localised prose explaining the revenue estimate. */
|
|
635
|
+
estimatedRevenueExplanation: string | null;
|
|
636
|
+
/** Server-localised disclaimer about long-term engagement assumptions. */
|
|
637
|
+
longTermDisclaimer: string | null;
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Rate insight when the talent's rate (or default rate) is judged
|
|
641
|
+
* UNCOMPETITIVE relative to the job's market (#424).
|
|
642
|
+
* Discriminated-union member of {@link RateInsight}; surfaces the
|
|
643
|
+
* captured wire's `TalentJobRateInsightUncompetitive` fields verbatim.
|
|
644
|
+
*
|
|
645
|
+
* `recentApplicationRate` + `recommendedRate` together form the
|
|
646
|
+
* "range guidance" the apply path uses to inform the talent
|
|
647
|
+
* (`recentApplicationRate` = empirical rate of recent successful
|
|
648
|
+
* applicants on this specific job; `recommendedRate` = Toptal's
|
|
649
|
+
* suggested rate to be competitive). Both are `BigDecimal`
|
|
650
|
+
* decimal-string scalars on the wire.
|
|
651
|
+
*/
|
|
652
|
+
export interface UncompetitiveRateInsight {
|
|
653
|
+
kind: "uncompetitive";
|
|
654
|
+
estimatedRevenue: string | null;
|
|
655
|
+
estimatedRevenueExplanation: string | null;
|
|
656
|
+
/** Empirical rate of recent successful applicants (BigDecimal scalar). */
|
|
657
|
+
recentApplicationRate: string | null;
|
|
658
|
+
/** Toptal's suggested rate to be competitive (BigDecimal scalar). */
|
|
659
|
+
recommendedRate: string | null;
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Discriminated-union projection of the wire's `TalentJobRateInsight`
|
|
663
|
+
* union (members `TalentJobRateInsightCompetitive` |
|
|
664
|
+
* `TalentJobRateInsightUncompetitive`). The `kind` discriminant
|
|
665
|
+
* narrows access to the variant-specific fields. Returned by
|
|
666
|
+
* {@link rateInsight}; `null` when the gateway omits the rate-insight
|
|
667
|
+
* payload (viewer null, job null, or `rateInsight` field null).
|
|
668
|
+
*/
|
|
669
|
+
export type RateInsight = CompetitiveRateInsight | UncompetitiveRateInsight;
|
|
670
|
+
/**
|
|
671
|
+
* Pre-apply aggregate context for a job (#424). Wraps `JobApplyData
|
|
672
|
+
* ($jobId)` — the mobile gateway's aggregate pre-apply query — and
|
|
673
|
+
* trims the response to the load-bearing scalars (REQ-A4 rate
|
|
674
|
+
* default, apply-state errors, platform validation bounds, plus
|
|
675
|
+
* basic job context). The captured operation also pulls in the
|
|
676
|
+
* pitch / talent-card / market-condition cascades; those are
|
|
677
|
+
* deliberately elided here. The apply path (#426) takes the pitch
|
|
678
|
+
* from `--pitch-file` per ADR-008's grammar, NOT from
|
|
679
|
+
* `suggestedPitch` / `lastPitches`, and `applyQuestions` /
|
|
680
|
+
* `rateInsight` cover the other captured slices. Future widening is
|
|
681
|
+
* additive.
|
|
682
|
+
*
|
|
683
|
+
* **Wire authority**: hand-authored from the captured
|
|
684
|
+
* `JobApplyData.graphql` selection set; CLAUDE.md schema/contract
|
|
685
|
+
* rule TRIGGERED for #424, live E2E coverage in #445.
|
|
686
|
+
*
|
|
687
|
+
* **Bad-id behavior**: `viewer.job(id:)` returns the Relay decode
|
|
688
|
+
* error (per `project-toptal-wire-quirks` memory) when the supplied
|
|
689
|
+
* id doesn't resolve to a viewable job; remapped to
|
|
690
|
+
* `ApplicationsError("NOT_FOUND")` via the shared
|
|
691
|
+
* {@link NOT_FOUND_MESSAGE_PATTERN} (widened in #424).
|
|
692
|
+
*
|
|
693
|
+
* @throws `ApplicationsError("NOT_FOUND")` when the job id doesn't
|
|
694
|
+
* resolve (Relay decode error, `Invalid ID`, `Record not found`,
|
|
695
|
+
* or successful response with `viewer.job === null`).
|
|
696
|
+
* @throws `ApplicationsError("NO_VIEWER")` when the session is valid
|
|
697
|
+
* but no viewer is bound (defensive — `callGateway` with
|
|
698
|
+
* `requireViewer: true` already raises this case, but the
|
|
699
|
+
* post-call null check keeps the type narrowing clean).
|
|
700
|
+
*/
|
|
701
|
+
export declare function applyData(token: string, jobId: string): Promise<PreApplyData>;
|
|
702
|
+
/**
|
|
703
|
+
* Pre-apply matcher + expertise questions inventory for a job (#424).
|
|
704
|
+
* Wraps `JobApplicationQuestions($jobId)`; trims the captured
|
|
705
|
+
* operation's `subject.possibleAnswers` cascades — the four-field
|
|
706
|
+
* {@link ApplicationQuestion} shape is the public projection per
|
|
707
|
+
* #424 AC.
|
|
708
|
+
*
|
|
709
|
+
* The two arrays surface verbatim presence: empty when the job has
|
|
710
|
+
* no questions of that kind. Order is server-supplied; no
|
|
711
|
+
* client-side re-sorting.
|
|
712
|
+
*
|
|
713
|
+
* **Bad-id behavior + NOT_FOUND mapping**: identical to
|
|
714
|
+
* {@link applyData}.
|
|
715
|
+
*
|
|
716
|
+
* @throws `ApplicationsError("NOT_FOUND")` for unresolved job ids.
|
|
717
|
+
* @throws `ApplicationsError("NO_VIEWER")` for sessions with no
|
|
718
|
+
* bound viewer.
|
|
719
|
+
*/
|
|
720
|
+
export declare function applyQuestions(token: string, jobId: string): Promise<ApplicationQuestions>;
|
|
721
|
+
/**
|
|
722
|
+
* Pre-apply rate guidance for a job (#424). Wraps
|
|
723
|
+
* `JobApplicationRateInsight($jobId)`; surfaces the captured
|
|
724
|
+
* operation's `TalentJobRateInsight` discriminated union as
|
|
725
|
+
* {@link RateInsight}. Returns `null` when the gateway omits the
|
|
726
|
+
* insight payload (the `rateInsight` field on the job resolves to
|
|
727
|
+
* null).
|
|
728
|
+
*
|
|
729
|
+
* The operation declares `$requestedRate: BigDecimal` (verbatim from
|
|
730
|
+
* the captured wire) but the public signature does NOT expose
|
|
731
|
+
* `requestedRate` per #424 AC — the variable is threaded as `null`,
|
|
732
|
+
* which the gateway treats as "show me the insight for the talent's
|
|
733
|
+
* default rate". Re-exposing the parameter is a future widening.
|
|
734
|
+
*
|
|
735
|
+
* **Wire shape**: union members carry `BigDecimal` scalar fields
|
|
736
|
+
* (`estimatedRevenue`, `recommendedRate`, `recentApplicationRate`)
|
|
737
|
+
* — NOT `Money { decimal verbose }` objects. The captured
|
|
738
|
+
* `JobApplicationRateInsight.graphql` operation selects them bare
|
|
739
|
+
* (no sub-selection), and the synthesized schema confirms
|
|
740
|
+
* `BigDecimal`. The #424 issue parenthetical "Money shape `{ decimal,
|
|
741
|
+
* verbose }` + range guidance" reflects an intuition rather than the
|
|
742
|
+
* captured wire; the captured operation's selection set is
|
|
743
|
+
* authoritative per the issue's own primary directive ("define shape
|
|
744
|
+
* based on captured operation's selection set"). PR body documents
|
|
745
|
+
* the deviation.
|
|
746
|
+
*
|
|
747
|
+
* **Bad-id behavior + NOT_FOUND mapping**: identical to
|
|
748
|
+
* {@link applyData}.
|
|
749
|
+
*
|
|
750
|
+
* @throws `ApplicationsError("NOT_FOUND")` for unresolved job ids.
|
|
751
|
+
* @throws `ApplicationsError("NO_VIEWER")` for sessions with no
|
|
752
|
+
* bound viewer.
|
|
753
|
+
*/
|
|
754
|
+
export declare function rateInsight(token: string, jobId: string): Promise<RateInsight | null>;
|
|
476
755
|
/**
|
|
477
756
|
* Confirm an Interest Request — wire `ConfirmAvailabilityRequest` (#411).
|
|
478
757
|
*
|
|
@@ -536,4 +815,629 @@ export declare function reject(token: string, id: string, input: RejectInput, op
|
|
|
536
815
|
* field is non-null in the schema; absence is wire-shape drift).
|
|
537
816
|
*/
|
|
538
817
|
export declare function rejectReasons(token: string): Promise<AvailabilityRequestRejectReasons>;
|
|
818
|
+
/**
|
|
819
|
+
* Input for {@link apply}. Field names mirror ADR-008's locked grammar
|
|
820
|
+
* (`matcherAnswers` / `expertiseAnswers` / `pitchData` / `message`)
|
|
821
|
+
* which is the MCP-side schema key set, NOT the wire-side variable
|
|
822
|
+
* names (`matcherQuestionsAnswers`, `expertiseQuestionsAnswers`,
|
|
823
|
+
* `talentCard`, `comment`). The service maps the public field names
|
|
824
|
+
* onto the wire variables internally.
|
|
825
|
+
*
|
|
826
|
+
* **Consent gate**: `consentIssued` is the literal `true` — the
|
|
827
|
+
* tightest type-system constraint TS supports, matching ADR-008
|
|
828
|
+
* § Decision Part 4. The runtime check covers `as`-cast bypasses
|
|
829
|
+
* and JSON-sourced inputs from the CLI/MCP layers where the type
|
|
830
|
+
* system can't reach. Auto-filling consent on the caller's behalf is
|
|
831
|
+
* FORBIDDEN by the same ADR; the service throws
|
|
832
|
+
* `CONSENT_REQUIRED` BEFORE any wire call when omitted.
|
|
833
|
+
*
|
|
834
|
+
* **Rate default**: `requestedHourlyRate` is optional at the input
|
|
835
|
+
* surface. When omitted, the service threads
|
|
836
|
+
* `PreApplyData.suggestedRate` (the talent's own configured rate
|
|
837
|
+
* `viewerRole.rates.hourly`) into the mutation per REQ-A4. If the
|
|
838
|
+
* talent has no configured rate, the service throws `MUTATION_ERROR`.
|
|
839
|
+
* The `rateInsight` payload returned by the pre-fetch suite serves as
|
|
840
|
+
* additional guidance for the caller (CLI / MCP / agent) — not as a
|
|
841
|
+
* silent default; callers surface it to the user before the apply.
|
|
842
|
+
*
|
|
843
|
+
* **Answer arrays**: `matcherAnswers` / `expertiseAnswers` are typed
|
|
844
|
+
* against the recovered `JobPositionAnswerInput[]` /
|
|
845
|
+
* `JobExpertiseAnswerInput[]` shapes (Stage 2 per #438; the recovered
|
|
846
|
+
* schemas are committed in `packages/core/src/__generated__/zod-schemas.ts`).
|
|
847
|
+
* The service validates each entry's id field against the inventory
|
|
848
|
+
* returned by `applyQuestions(jobId)` and rejects unknown ids with
|
|
849
|
+
* `WIRE_SHAPE_ERROR`. The id-field name is **asymmetric** per the
|
|
850
|
+
* recovered SDL — matcher entries carry `id`, expertise entries carry
|
|
851
|
+
* `questionId`.
|
|
852
|
+
*/
|
|
853
|
+
export interface ApplyInput {
|
|
854
|
+
/**
|
|
855
|
+
* Consent attestation — MUST be the literal `true`. Auto-filling
|
|
856
|
+
* this field on the caller's behalf is FORBIDDEN per ADR-008
|
|
857
|
+
* § Decision Part 4 (legal compliance).
|
|
858
|
+
*/
|
|
859
|
+
consentIssued: true;
|
|
860
|
+
/**
|
|
861
|
+
* Hourly rate the talent requests for this engagement. Decimal
|
|
862
|
+
* string (matches `BigDecimal!`). When omitted, the service
|
|
863
|
+
* defaults from `PreApplyData.suggestedRate` (REQ-A4).
|
|
864
|
+
*/
|
|
865
|
+
requestedHourlyRate?: string;
|
|
866
|
+
/**
|
|
867
|
+
* Optional talent-side free-text accompanying message. Mapped to
|
|
868
|
+
* the wire's `$comment` variable / `JobApplyInput.comment` field.
|
|
869
|
+
*/
|
|
870
|
+
message?: string;
|
|
871
|
+
/**
|
|
872
|
+
* Matcher-question answers (`JobPositionAnswerInput[]`). Each
|
|
873
|
+
* entry MUST carry an `id` field matching one returned from
|
|
874
|
+
* `applyQuestions(jobId).matcherQuestions[].identifier` — the
|
|
875
|
+
* service rejects unknown ids with `WIRE_SHAPE_ERROR`. Stage 2
|
|
876
|
+
* (#438) types the array against the recovered SDL shape
|
|
877
|
+
* `{ answer: string, id: string }` (NOT `questionId` — distinct
|
|
878
|
+
* from the expertise shape; this field-name asymmetry is per the
|
|
879
|
+
* recovered SDL).
|
|
880
|
+
*/
|
|
881
|
+
matcherAnswers?: JobPositionAnswerInput[];
|
|
882
|
+
/**
|
|
883
|
+
* Expertise-question answers (`JobExpertiseAnswerInput[]`). Each
|
|
884
|
+
* entry's `questionId` is validated against
|
|
885
|
+
* `applyQuestions(jobId).expertiseQuestions[].identifier`. Stage 2
|
|
886
|
+
* (#438) types the array against the recovered SDL shape
|
|
887
|
+
* `{ other: string|null, questionId: string, subjectId: string|null }`.
|
|
888
|
+
*/
|
|
889
|
+
expertiseAnswers?: JobExpertiseAnswerInput[];
|
|
890
|
+
/**
|
|
891
|
+
* Pitch input (`PitchInput`). Mapped to the wire's `$talentCard`
|
|
892
|
+
* variable / `JobApplyInput.pitchData` field. Stage 2 (#438) types
|
|
893
|
+
* the field against the recovered `PitchInput` shape (`mentorship`
|
|
894
|
+
* remains `unknown` per ADR-008 spike outcome — the position is
|
|
895
|
+
* untyped in the SDL).
|
|
896
|
+
*/
|
|
897
|
+
pitchData?: PitchInput;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Projected `JobApplication` record returned by {@link apply} on the
|
|
901
|
+
* apply-success path. Reads the post-mutation `JobApplication` echo
|
|
902
|
+
* routed through the new activity-item's nested `jobApplication`
|
|
903
|
+
* field on `TalentJob.activityItem`.
|
|
904
|
+
*
|
|
905
|
+
* Shape is the conservative initial projection per #426 AC; #445 live
|
|
906
|
+
* E2E is the wire authority and may widen the projection if real
|
|
907
|
+
* responses surface fields the CLI / MCP need to render.
|
|
908
|
+
*/
|
|
909
|
+
export interface JobApplicationRecord {
|
|
910
|
+
/** `JobApplication.id` — the new application's identifier. */
|
|
911
|
+
id: string;
|
|
912
|
+
/** Application status (specific value + verbose label, projected from `TalentJobActivityItem.statusV2`). */
|
|
913
|
+
statusV2: ApplicationStatus;
|
|
914
|
+
/**
|
|
915
|
+
* The rate the wire echoes back on the new `JobApplication`. The
|
|
916
|
+
* captured op selects `requestedHourlyRate { decimal }` only — no
|
|
917
|
+
* `verbose` — and the projection mirrors that selection until #445
|
|
918
|
+
* confirms `verbose` is selectable on this position.
|
|
919
|
+
*/
|
|
920
|
+
requestedHourlyRate: {
|
|
921
|
+
decimal: string;
|
|
922
|
+
} | null;
|
|
923
|
+
/**
|
|
924
|
+
* The `TalentJobActivityItem.id` that wraps the new application —
|
|
925
|
+
* the id callers pass to `applications show` to view the new row.
|
|
926
|
+
*/
|
|
927
|
+
jobActivityItemId: string;
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Apply-path outcome for {@link apply}. Carries the post-mutation
|
|
931
|
+
* {@link JobApplicationRecord} projection.
|
|
932
|
+
*/
|
|
933
|
+
export interface JobApplyAppliedOutcome {
|
|
934
|
+
kind: "applied";
|
|
935
|
+
result: JobApplicationRecord;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Dry-run outcome for {@link apply}. Mirrors the
|
|
939
|
+
* `AvailabilityRequestDryRunPreviewOutcome` pattern from #411 —
|
|
940
|
+
* named separately for surface symmetry on the apply path.
|
|
941
|
+
*/
|
|
942
|
+
export interface JobApplyDryRunPreviewOutcome {
|
|
943
|
+
kind: "preview";
|
|
944
|
+
preview: DryRunPreview;
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Discriminated-union return type for {@link apply}.
|
|
948
|
+
*/
|
|
949
|
+
export type ApplyOutcome = JobApplyAppliedOutcome | JobApplyDryRunPreviewOutcome;
|
|
950
|
+
/**
|
|
951
|
+
* Direct-apply to a Toptal job — wire `JobApply` (#426, ADR-008
|
|
952
|
+
* § Decision Part 5).
|
|
953
|
+
*
|
|
954
|
+
* Flow:
|
|
955
|
+
*
|
|
956
|
+
* 1. **Consent gate**: refuses the call (`CONSENT_REQUIRED`) BEFORE
|
|
957
|
+
* any wire call when `input.consentIssued !== true`. Type-system
|
|
958
|
+
* gate at `ApplyInput.consentIssued: true` covers compile-time;
|
|
959
|
+
* the runtime check covers `as`-cast bypasses and JSON-sourced
|
|
960
|
+
* inputs.
|
|
961
|
+
* 2. **Dry-run short-circuit**: when `options.dryRun === true`,
|
|
962
|
+
* emits a {@link DryRunPreview} with the prepared variables
|
|
963
|
+
* (including `<resolved at apply time>` placeholders for fields
|
|
964
|
+
* that would have been resolved by the pre-fetch) and returns
|
|
965
|
+
* `{ kind: "preview", preview }`. Zero wire calls under dry-run —
|
|
966
|
+
* including the 3 pre-fetch calls.
|
|
967
|
+
* 3. **Pre-fetch via Promise.all**: runs `applyData` +
|
|
968
|
+
* `applyQuestions` + `rateInsight` concurrently. Promise.all
|
|
969
|
+
* rejects-on-first; any pre-fetch failure (NOT_FOUND,
|
|
970
|
+
* GRAPHQL_ERROR, AuthRevokedError) blocks the apply.
|
|
971
|
+
* 4. **Answer validation**: every `matcherAnswers[]` /
|
|
972
|
+
* `expertiseAnswers[]` entry's `questionId` must resolve against
|
|
973
|
+
* the inventory; unknown ids throw `WIRE_SHAPE_ERROR` with the
|
|
974
|
+
* offending array path.
|
|
975
|
+
* 5. **Rate default**: when `input.requestedHourlyRate` is omitted,
|
|
976
|
+
* threads `PreApplyData.suggestedRate` (the talent's own
|
|
977
|
+
* configured rate). Throws `MUTATION_ERROR` if neither source
|
|
978
|
+
* yields a rate.
|
|
979
|
+
* 6. **Wire call**: issues `JobApply` against the mobile gateway.
|
|
980
|
+
* 7. **Error mapping**: a `MutationResult.errors[]` entry with
|
|
981
|
+
* `key === "already_applied"` is mapped to `ALREADY_APPLIED`
|
|
982
|
+
* with a hint pointing at `ttctl applications show
|
|
983
|
+
* <activity-id>`. Other `success: false` responses surface as
|
|
984
|
+
* `MUTATION_ERROR` with the formatted error detail.
|
|
985
|
+
*
|
|
986
|
+
* **Bad-id behavior**: mutations crash 500 on bad ids per
|
|
987
|
+
* `project-toptal-wire-quirks` auto-memory. The service does NOT
|
|
988
|
+
* pre-validate the job id; the pre-fetch suite (`applyData` etc.)
|
|
989
|
+
* already surfaces NOT_FOUND via the shared widened
|
|
990
|
+
* {@link NOT_FOUND_MESSAGE_PATTERN} when the bad id is detected
|
|
991
|
+
* read-side.
|
|
992
|
+
*/
|
|
993
|
+
export declare function apply(token: string, jobId: string, input: ApplyInput, options?: DryRunOptions): Promise<ApplyOutcome>;
|
|
994
|
+
/**
|
|
995
|
+
* One historical answer to a question similar to the queried one.
|
|
996
|
+
* Wire selection: `JobPositionAnswer { id answer createdAt }` per the
|
|
997
|
+
* captured `SimilarJobQuestionAnswers.graphql` operation. `createdAt`
|
|
998
|
+
* is selected on a schema-gap position (`JobPositionAnswer.createdAt`
|
|
999
|
+
* is not declared on the synthesized SDL — see the schema-gap note in
|
|
1000
|
+
* the inline query string below); the projection is `string` here per
|
|
1001
|
+
* the empirical wire shape, the T1 snapshot is the authority.
|
|
1002
|
+
*/
|
|
1003
|
+
export interface SimilarJobAnswer {
|
|
1004
|
+
/** `JobPositionAnswer.id` — the historical answer's identifier. */
|
|
1005
|
+
id: string;
|
|
1006
|
+
/** The historical answer text (`JobPositionAnswer.answer`). */
|
|
1007
|
+
answer: string;
|
|
1008
|
+
/** ISO 8601 timestamp the historical answer was authored. */
|
|
1009
|
+
createdAt: string;
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* One group of suggestions, keyed by the question identifier the
|
|
1013
|
+
* suggestions were resolved against. `questionId` mirrors the wire
|
|
1014
|
+
* filter (`forQuestionsSimilarToQuestionId: <questionId>`). The
|
|
1015
|
+
* `suggestions` array carries the talent's own historical answers to
|
|
1016
|
+
* SIMILAR questions on prior applications — useful as autocomplete
|
|
1017
|
+
* candidates the user can review and selectively re-use when authoring
|
|
1018
|
+
* an application.
|
|
1019
|
+
*
|
|
1020
|
+
* Empty `suggestions` arrays surface verbatim: the wire returned zero
|
|
1021
|
+
* similar-job history for this question. Common for new talent
|
|
1022
|
+
* accounts and unique question prompts.
|
|
1023
|
+
*/
|
|
1024
|
+
export interface SimilarJobAnswerGroup {
|
|
1025
|
+
/**
|
|
1026
|
+
* The `ApplicationQuestion.identifier` (from
|
|
1027
|
+
* {@link ApplicationQuestion}) the suggestions were resolved
|
|
1028
|
+
* against — both matcher and expertise question identifiers are
|
|
1029
|
+
* accepted.
|
|
1030
|
+
*/
|
|
1031
|
+
questionId: string;
|
|
1032
|
+
/**
|
|
1033
|
+
* Historical answers to questions semantically similar to the one
|
|
1034
|
+
* identified by `questionId`. Order is server-supplied; the helper
|
|
1035
|
+
* does NOT re-sort.
|
|
1036
|
+
*/
|
|
1037
|
+
suggestions: SimilarJobAnswer[];
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Fetch the talent's similar-answer suggestions for every question on
|
|
1041
|
+
* a job's apply form (#452).
|
|
1042
|
+
*
|
|
1043
|
+
* Returns one {@link SimilarJobAnswerGroup} per question — matcher
|
|
1044
|
+
* AND expertise. The order mirrors the underlying
|
|
1045
|
+
* {@link applyQuestions} inventory (matcher questions first, then
|
|
1046
|
+
* expertise; server-supplied order within each section).
|
|
1047
|
+
*
|
|
1048
|
+
* **Cardinality**: N+1 wire calls — first an {@link applyQuestions}
|
|
1049
|
+
* fetch to resolve the question identifier list, then N parallel
|
|
1050
|
+
* `SimilarJobQuestionAnswers` calls (one per question) via
|
|
1051
|
+
* `Promise.all`. The fan-out matches the mobile app's apply-screen
|
|
1052
|
+
* autocomplete behavior; aggregating server-side is not exposed by
|
|
1053
|
+
* the wire.
|
|
1054
|
+
*
|
|
1055
|
+
* **Bad-id behavior**: a bad `jobId` surfaces NOT_FOUND from
|
|
1056
|
+
* `applyQuestions` (same mapping as the rest of the pre-apply suite).
|
|
1057
|
+
* A per-question `SimilarJobQuestionAnswers` call that surfaces
|
|
1058
|
+
* NOT_FOUND propagates verbatim via `Promise.all`'s reject-on-first
|
|
1059
|
+
* — intentional: callers that want graceful per-question fallback
|
|
1060
|
+
* (e.g. the CLI's `--suggest-answers` flag) should catch the rejection
|
|
1061
|
+
* and continue without suggestions.
|
|
1062
|
+
*
|
|
1063
|
+
* **Performance**: when the job has zero questions, the call resolves
|
|
1064
|
+
* to `[]` after the single `applyQuestions` fetch — no wasted parallel
|
|
1065
|
+
* round-trips. When the job has questions but the talent's account
|
|
1066
|
+
* has no similar-job history, each per-question call returns an empty
|
|
1067
|
+
* `suggestions` array; surface the empty grouping verbatim.
|
|
1068
|
+
*
|
|
1069
|
+
* **Off the critical apply path**: this fn is NOT called from
|
|
1070
|
+
* {@link apply}. It's opt-in via the CLI's `--suggest-answers` flag
|
|
1071
|
+
* (#452) and the MCP's `ttctl_jobs_apply_similar_answers` tool. The
|
|
1072
|
+
* design rationale is in the ADR-008 follow-ups thread.
|
|
1073
|
+
*
|
|
1074
|
+
* @param token - Bearer token from the resolved auth config.
|
|
1075
|
+
* @param jobId - The `TalentJob.id` to resolve questions against.
|
|
1076
|
+
* @throws `ApplicationsError("NOT_FOUND")` when the jobId or a
|
|
1077
|
+
* resolved questionId doesn't resolve.
|
|
1078
|
+
* @throws `ApplicationsError("NO_VIEWER")` for sessions with no
|
|
1079
|
+
* bound viewer.
|
|
1080
|
+
*/
|
|
1081
|
+
export declare function similarAnswers(token: string, jobId: string): Promise<SimilarJobAnswerGroup[]>;
|
|
1082
|
+
/**
|
|
1083
|
+
* `InterviewStatusEnum` values from the synthesized schema
|
|
1084
|
+
* (`../research/graphql/gateway/schema.graphql`). Closed set.
|
|
1085
|
+
*/
|
|
1086
|
+
export type InterviewStatus = "ACCEPTED" | "MISSED" | "PENDING" | "REJECTED" | "SCHEDULED" | "TIME_ACCEPTED" | "TIME_REJECTED";
|
|
1087
|
+
export declare const INTERVIEW_STATUSES: readonly InterviewStatus[];
|
|
1088
|
+
/**
|
|
1089
|
+
* `InterviewKindEnum` values from the synthesized schema. `INTERNAL`
|
|
1090
|
+
* = interview between talent and Toptal (vetting); `EXTERNAL` =
|
|
1091
|
+
* interview between talent and client (post-match).
|
|
1092
|
+
*/
|
|
1093
|
+
export type InterviewKind = "EXTERNAL" | "INTERNAL";
|
|
1094
|
+
/**
|
|
1095
|
+
* `TalentInterviewMethodTypeEnum` values from the synthesized schema.
|
|
1096
|
+
* Typed as a string for forward compatibility with un-enumerated future
|
|
1097
|
+
* members (the wire is untrusted; new method types may appear without
|
|
1098
|
+
* codegen warning).
|
|
1099
|
+
*/
|
|
1100
|
+
export type InterviewMethodType = string;
|
|
1101
|
+
/**
|
|
1102
|
+
* Time-zone descriptor. `value` is the IANA-ish zone name; `location`
|
|
1103
|
+
* is a human-readable label. Either may be `null` when the wire omits
|
|
1104
|
+
* the field.
|
|
1105
|
+
*/
|
|
1106
|
+
export interface InterviewTimeZone {
|
|
1107
|
+
value: string | null;
|
|
1108
|
+
location: string | null;
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* One interviewer-side contact (recruiter, client representative, etc.).
|
|
1112
|
+
* `main: true` flags the primary contact on the interview.
|
|
1113
|
+
*/
|
|
1114
|
+
export interface InterviewContact {
|
|
1115
|
+
id: string;
|
|
1116
|
+
fullName: string | null;
|
|
1117
|
+
email: string | null;
|
|
1118
|
+
phoneNumber: string | null;
|
|
1119
|
+
position: string | null;
|
|
1120
|
+
main: boolean | null;
|
|
1121
|
+
timeZone: InterviewTimeZone | null;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Method by which the interview will be conducted (Zoom, phone, etc.).
|
|
1125
|
+
*
|
|
1126
|
+
* - `typeV2` — one of the `TalentInterviewMethodTypeEnum` members
|
|
1127
|
+
* (`ZOOM`, `PHONE`, `BLUEJEANS`, `CUSTOM_WEB_CONFERENCE`,
|
|
1128
|
+
* `GOOGLE_HANGOUTS`, `SKYPE`). Stringly-typed because the wire is
|
|
1129
|
+
* untrusted; the codegen-exclusion may add new members.
|
|
1130
|
+
* - `conferenceUrl` — meeting link for `ZOOM` / `BLUEJEANS` /
|
|
1131
|
+
* `GOOGLE_HANGOUTS` / `CUSTOM_WEB_CONFERENCE` methods.
|
|
1132
|
+
* - `resource` — free-text channel string (phone number for `PHONE`,
|
|
1133
|
+
* handle for `SKYPE`).
|
|
1134
|
+
*/
|
|
1135
|
+
export interface InterviewMethod {
|
|
1136
|
+
typeV2: InterviewMethodType | null;
|
|
1137
|
+
conferenceUrl: string | null;
|
|
1138
|
+
resource: string | null;
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* One free-form note the talent has attached to the interview. `section`
|
|
1142
|
+
* is one of the `InterviewGuideSectionIdentifierEnum` members
|
|
1143
|
+
* (`ASK_YOUR_CLIENT`, `GAPS`, `JOB_HIGHLIGHTS`, `POTENTIAL_QUESTIONS`,
|
|
1144
|
+
* `PRO_TIPS`, `STRENGTHS`) or `null` when the note isn't section-pinned.
|
|
1145
|
+
*/
|
|
1146
|
+
export interface InterviewTalentNote {
|
|
1147
|
+
id: string;
|
|
1148
|
+
section: string | null;
|
|
1149
|
+
note: string | null;
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Back-pointer to the parent job + activity item. Presence indicators
|
|
1153
|
+
* only — the CLI surfaces them as discovery hints (`applications show
|
|
1154
|
+
* <activityId>` to drill into the full activity row).
|
|
1155
|
+
*/
|
|
1156
|
+
export interface InterviewJobRef {
|
|
1157
|
+
/** `TalentJob.id`. */
|
|
1158
|
+
id: string;
|
|
1159
|
+
/** `TalentJobActivityItem.id` for the activity row containing this interview. */
|
|
1160
|
+
activityItemId: string | null;
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Projected interview detail returned by `interviews.show()`. The shape
|
|
1164
|
+
* the CLI's pretty renderer and the MCP tool's JSON payload depend on.
|
|
1165
|
+
*/
|
|
1166
|
+
export interface InterviewDetail {
|
|
1167
|
+
id: string;
|
|
1168
|
+
/** `InterviewStatusEnum` member (see {@link INTERVIEW_STATUSES}) or null. */
|
|
1169
|
+
status: InterviewStatus | null;
|
|
1170
|
+
/** `InterviewKindEnum` member or null. */
|
|
1171
|
+
kind: InterviewKind | null;
|
|
1172
|
+
/** Free-text interview-type label (legacy; modern wire prefers {@link kind}). */
|
|
1173
|
+
interviewType: string | null;
|
|
1174
|
+
/** Duration / display string (e.g. `"30 minutes"`). */
|
|
1175
|
+
interviewTime: string | null;
|
|
1176
|
+
/** Recruiter brief, markdown-formatted. */
|
|
1177
|
+
information: string | null;
|
|
1178
|
+
/** Who scheduled the interview (display string). */
|
|
1179
|
+
initiator: string | null;
|
|
1180
|
+
/** Proposed slot timestamps (ISO 8601). */
|
|
1181
|
+
scheduledAtTimes: string[];
|
|
1182
|
+
/** Free-text scheduling comment from the initiator. */
|
|
1183
|
+
schedulingComment: string | null;
|
|
1184
|
+
/** Conference method (Zoom, phone, …) — `null` until the slot is locked. */
|
|
1185
|
+
method: InterviewMethod | null;
|
|
1186
|
+
/** Interviewer contacts. Server-supplied order preserved. */
|
|
1187
|
+
contacts: InterviewContact[];
|
|
1188
|
+
/** Prep-guide id (presence indicator). Full guide is the `InterviewGuide` op, out of scope here. */
|
|
1189
|
+
guideId: string | null;
|
|
1190
|
+
/** Talent's own notes attached to the interview. Server order preserved. */
|
|
1191
|
+
talentNotes: InterviewTalentNote[];
|
|
1192
|
+
/** Back-pointer to the parent job + activity item. */
|
|
1193
|
+
job: InterviewJobRef | null;
|
|
1194
|
+
/** Server-supplied last-mutation timestamp (ISO 8601). */
|
|
1195
|
+
updatedAt: string | null;
|
|
1196
|
+
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Read one `TalentInterview` by id via the mobile-gateway `Interview`
|
|
1199
|
+
* query (#439). Sibling sub-namespace to the top-level activity-row
|
|
1200
|
+
* leaves (`list` / `show` / `stats`) — fetches the rich interview
|
|
1201
|
+
* detail once the user knows the id from `applications show
|
|
1202
|
+
* <activityId>` (the `Interview: <id>` line).
|
|
1203
|
+
*
|
|
1204
|
+
* @throws `ApplicationsError("NOT_FOUND")` when the id doesn't resolve
|
|
1205
|
+
* to an interview the signed-in user can see, OR when the wire
|
|
1206
|
+
* surfaces a `NOT_FOUND_MESSAGE_PATTERN`-matched GraphQL error
|
|
1207
|
+
* (`Record not found` / `Invalid ID` / Relay `Node id ... resolves to`).
|
|
1208
|
+
* @throws `ApplicationsError("NO_VIEWER")` when the session is valid
|
|
1209
|
+
* but no viewer is bound.
|
|
1210
|
+
*/
|
|
1211
|
+
declare function interviewsShow(token: string, id: string): Promise<InterviewDetail>;
|
|
1212
|
+
/**
|
|
1213
|
+
* Projected response returned by `interviews.notes.show()`. Shape the
|
|
1214
|
+
* CLI's pretty renderer and the MCP tool's JSON payload depend on.
|
|
1215
|
+
*
|
|
1216
|
+
* `jobId` is the input echo (always populated). `interviewId` /
|
|
1217
|
+
* `interviewKind` are populated when the job has an attached interview;
|
|
1218
|
+
* `null` when the job's `activityItem.interview` is null on the wire
|
|
1219
|
+
* (e.g. the job exists but no interview was scheduled). `notes`
|
|
1220
|
+
* preserves server order; empty array when the interview has no
|
|
1221
|
+
* recorded prep notes.
|
|
1222
|
+
*/
|
|
1223
|
+
export interface InterviewNotesProjection {
|
|
1224
|
+
jobId: string;
|
|
1225
|
+
interviewId: string | null;
|
|
1226
|
+
interviewKind: InterviewKind | null;
|
|
1227
|
+
notes: InterviewTalentNote[];
|
|
1228
|
+
}
|
|
1229
|
+
/**
|
|
1230
|
+
* Read the talent's prep notes for the interview attached to a given
|
|
1231
|
+
* job via the portal-side `GetInterviewNotes` query (#440). Sub-sub-
|
|
1232
|
+
* namespace leaf of `applications.interviews.*` — wraps the same
|
|
1233
|
+
* read-only path the portal matcher UI uses to load interview notes.
|
|
1234
|
+
*
|
|
1235
|
+
* @param token Captured bearer.
|
|
1236
|
+
* @param jobId `TalentJob.id` (NOT the interview id). Discover via
|
|
1237
|
+
* `applications interview show <interviewId>` (the
|
|
1238
|
+
* `Job → Job id` line, populated by the #439 projection)
|
|
1239
|
+
* or `applications show <activityId>`.
|
|
1240
|
+
*
|
|
1241
|
+
* @throws `ApplicationsError("NOT_FOUND")` when the job id doesn't
|
|
1242
|
+
* resolve to a job the signed-in user can see, OR when the wire
|
|
1243
|
+
* surfaces a `NOT_FOUND_MESSAGE_PATTERN`-matched GraphQL error
|
|
1244
|
+
* (`Record not found` / `Invalid ID` / Relay `Node id ... resolves to`).
|
|
1245
|
+
* @throws `ApplicationsError("NO_VIEWER")` when the session is valid
|
|
1246
|
+
* but no viewer is bound.
|
|
1247
|
+
*/
|
|
1248
|
+
declare function interviewsNotesShow(token: string, jobId: string): Promise<InterviewNotesProjection>;
|
|
1249
|
+
/**
|
|
1250
|
+
* `InterviewGuideSectionIdentifierEnum` values from the synthesized
|
|
1251
|
+
* schema (`../research/graphql/gateway/schema.graphql`). Closed set —
|
|
1252
|
+
* statically extractable from the schema. The mobile portal uses these
|
|
1253
|
+
* as the prep-guide section spine: `STRENGTHS` (talent's job-match
|
|
1254
|
+
* strengths), `GAPS` (likely follow-up topics), `JOB_HIGHLIGHTS` (key
|
|
1255
|
+
* job characteristics), `POTENTIAL_QUESTIONS` (questions to expect),
|
|
1256
|
+
* `PRO_TIPS` (Toptal interview tips), `ASK_YOUR_CLIENT` (questions to
|
|
1257
|
+
* ask the interviewer).
|
|
1258
|
+
*/
|
|
1259
|
+
export type InterviewGuideSectionIdentifier = "ASK_YOUR_CLIENT" | "GAPS" | "JOB_HIGHLIGHTS" | "POTENTIAL_QUESTIONS" | "PRO_TIPS" | "STRENGTHS";
|
|
1260
|
+
export declare const INTERVIEW_GUIDE_SECTION_IDENTIFIERS: readonly InterviewGuideSectionIdentifier[];
|
|
1261
|
+
/**
|
|
1262
|
+
* `InterviewGuideTipIdentifierEnum` values from the synthesized schema
|
|
1263
|
+
* (`../research/graphql/gateway/schema.graphql`). Closed set —
|
|
1264
|
+
* statically extractable from the schema. Each tip identifier is a
|
|
1265
|
+
* named template slot the Toptal guide-rendering pipeline fills with
|
|
1266
|
+
* job/talent-specific content.
|
|
1267
|
+
*/
|
|
1268
|
+
export type InterviewGuideTipIdentifier = "BE_PRESENTABLE" | "CAMERA_ON" | "DONT_DISCUSS_RATE" | "GAP_ANALYSIS" | "HIRING_FACTORS" | "JOB_SUMMARY" | "PROFILE_REFERENCES" | "QUESTIONS_TO_ASK" | "QUESTIONS_TO_PREPARE_FOR" | "SMALL_TALK" | "STANDARD_QUESTIONS" | "STRENGTHS_OVERLAP";
|
|
1269
|
+
export declare const INTERVIEW_GUIDE_TIP_IDENTIFIERS: readonly InterviewGuideTipIdentifier[];
|
|
1270
|
+
/**
|
|
1271
|
+
* One tip within an {@link InterviewGuideSection}. `content` is the
|
|
1272
|
+
* job/talent-personalized body (the Toptal guide-rendering pipeline
|
|
1273
|
+
* splices in job-specific examples); `hardcodedContent` is the generic
|
|
1274
|
+
* template body that ships with every guide regardless of job context.
|
|
1275
|
+
* Either or both may be populated; the renderer is responsible for
|
|
1276
|
+
* choosing precedence.
|
|
1277
|
+
*/
|
|
1278
|
+
export interface InterviewGuideTip {
|
|
1279
|
+
/** `InterviewGuideTipIdentifierEnum` member (see {@link INTERVIEW_GUIDE_TIP_IDENTIFIERS}) or null. */
|
|
1280
|
+
identifier: InterviewGuideTipIdentifier | null;
|
|
1281
|
+
title: string | null;
|
|
1282
|
+
/** Personalized tip body (markdown). May be null when no personalization applies. */
|
|
1283
|
+
content: string | null;
|
|
1284
|
+
/** Generic template body (markdown) shipped with every guide. May be null. */
|
|
1285
|
+
hardcodedContent: string | null;
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* One section of the interview-prep guide.
|
|
1289
|
+
*/
|
|
1290
|
+
export interface InterviewGuideSection {
|
|
1291
|
+
/** `InterviewGuideSectionIdentifierEnum` member (see {@link INTERVIEW_GUIDE_SECTION_IDENTIFIERS}) or null. */
|
|
1292
|
+
identifier: InterviewGuideSectionIdentifier | null;
|
|
1293
|
+
title: string | null;
|
|
1294
|
+
subtitle: string | null;
|
|
1295
|
+
/** Server-supplied order preserved. */
|
|
1296
|
+
tips: InterviewGuideTip[];
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Projected guide payload returned by `interviews.guide.show()`. Shape
|
|
1300
|
+
* the CLI's pretty renderer and the MCP tool's JSON payload depend on.
|
|
1301
|
+
*
|
|
1302
|
+
* `interviewId` is the input echo (always populated). `guideId` /
|
|
1303
|
+
* `sections` are populated when the interview has an attached guide;
|
|
1304
|
+
* `guideId` is `null` and `sections` is `[]` when no guide is attached
|
|
1305
|
+
* to the interview (some interview types may not have a prep guide).
|
|
1306
|
+
*/
|
|
1307
|
+
export interface InterviewGuideProjection {
|
|
1308
|
+
/** Input echo. */
|
|
1309
|
+
interviewId: string;
|
|
1310
|
+
/** `TalentInterviewGuide.id` — matches `InterviewDetail.guideId` from #439. `null` when no guide is attached. */
|
|
1311
|
+
guideId: string | null;
|
|
1312
|
+
/** Guide sections in server-supplied order. Empty array when no guide is attached. */
|
|
1313
|
+
sections: InterviewGuideSection[];
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Read the interview-prep guide content (sections + tips) for one
|
|
1317
|
+
* interview via the mobile-gateway `InterviewGuide` query (#470).
|
|
1318
|
+
* Sub-sub-namespace leaf of `applications.interviews.*` — wraps the
|
|
1319
|
+
* mobile-portal interview-prep view that talents use to prepare.
|
|
1320
|
+
*
|
|
1321
|
+
* @param token Captured bearer.
|
|
1322
|
+
* @param interviewId `TalentInterview.id` (NOT the guide id). Discover
|
|
1323
|
+
* via `applications interview show <interviewId>`
|
|
1324
|
+
* or `applications show <activityId>`.
|
|
1325
|
+
*
|
|
1326
|
+
* @throws `ApplicationsError("NOT_FOUND")` when the id doesn't resolve
|
|
1327
|
+
* to an interview the signed-in user can see, OR when the wire
|
|
1328
|
+
* surfaces a `NOT_FOUND_MESSAGE_PATTERN`-matched GraphQL error
|
|
1329
|
+
* (`Record not found` / `Invalid ID` / Relay `Node id ... resolves to`).
|
|
1330
|
+
* @throws `ApplicationsError("NO_VIEWER")` when the session is valid
|
|
1331
|
+
* but no viewer is bound.
|
|
1332
|
+
*/
|
|
1333
|
+
declare function interviewsGuideShow(token: string, interviewId: string): Promise<InterviewGuideProjection>;
|
|
1334
|
+
/**
|
|
1335
|
+
* `applications.interviews.*` sub-namespace. Read-only leaves for
|
|
1336
|
+
* interview-detail access — sibling to the top-level activity-row
|
|
1337
|
+
* leaves on this module. Sub-namespace grouping pattern follows
|
|
1338
|
+
* `payments.rate.*` (#447) and `payments.payouts.*` / `payments.methods.*`
|
|
1339
|
+
* (#149); the plural form here matches `payouts` / `methods` for
|
|
1340
|
+
* collection-style namespaces.
|
|
1341
|
+
*
|
|
1342
|
+
* Sub-sub-namespaces:
|
|
1343
|
+
* - `interviews.notes.*` (#440) — portal-side notes-focused projection.
|
|
1344
|
+
* `notes.show(jobId)` is the lightweight read of the talent's prep
|
|
1345
|
+
* notes for one job's interview, paired with the heavier
|
|
1346
|
+
* `interviews.show(interviewId)` from #439.
|
|
1347
|
+
* - `interviews.guide.*` (#470) — mobile-gateway guide-content
|
|
1348
|
+
* projection. `guide.show(interviewId)` is the read of the
|
|
1349
|
+
* interview-prep guide (sections + tips). Paired with #439 —
|
|
1350
|
+
* `interviews.show` surfaces the guide-id presence indicator;
|
|
1351
|
+
* `interviews.guide.show` fetches the full content.
|
|
1352
|
+
*/
|
|
1353
|
+
export declare const interviews: {
|
|
1354
|
+
show: typeof interviewsShow;
|
|
1355
|
+
notes: {
|
|
1356
|
+
show: typeof interviewsNotesShow;
|
|
1357
|
+
};
|
|
1358
|
+
guide: {
|
|
1359
|
+
show: typeof interviewsGuideShow;
|
|
1360
|
+
};
|
|
1361
|
+
};
|
|
1362
|
+
/**
|
|
1363
|
+
* `AvailabilityRequestStatusEnum` values from the synthesized schema
|
|
1364
|
+
* (`../research/graphql/gateway/schema.graphql`). Closed set — unlike
|
|
1365
|
+
* the INFERRED {@link AvailabilityRequestKind} enum, the status enum is
|
|
1366
|
+
* statically extractable from the schema.
|
|
1367
|
+
*
|
|
1368
|
+
* NB: distinct from the GraphQL schema type *named* `AvailabilityRequestStatus`
|
|
1369
|
+
* (the `{ value: String! }` wrapper that `statusV2` / `jirStatus`
|
|
1370
|
+
* resolve to). This TS type is the closed set of `.value` spellings.
|
|
1371
|
+
*/
|
|
1372
|
+
export type AvailabilityRequestStatus = "CANCELLED" | "CONFIRMED" | "EXPIRED" | "PENDING" | "REJECTED" | "WITHDRAWN";
|
|
1373
|
+
export declare const AVAILABILITY_REQUEST_STATUSES: readonly AvailabilityRequestStatus[];
|
|
1374
|
+
/**
|
|
1375
|
+
* Projected availability-request detail returned by
|
|
1376
|
+
* `availabilityRequests.show()`. The shape the CLI's pretty renderer
|
|
1377
|
+
* and the MCP tool's JSON payload depend on.
|
|
1378
|
+
*/
|
|
1379
|
+
export interface AvailabilityRequestDetail {
|
|
1380
|
+
id: string;
|
|
1381
|
+
/**
|
|
1382
|
+
* `AvailabilityRequestStatusEnum` member (see
|
|
1383
|
+
* {@link AVAILABILITY_REQUEST_STATUSES}) or `null`. Read off the
|
|
1384
|
+
* wire's `jirStatus` (aliased `statusV2`) `{ value }` wrapper.
|
|
1385
|
+
*/
|
|
1386
|
+
status: AvailabilityRequestStatus | null;
|
|
1387
|
+
/**
|
|
1388
|
+
* AR kind, auto-detected from `metadata.__typename` via
|
|
1389
|
+
* {@link kindFromMetadataTypename}. `null` when metadata is absent or
|
|
1390
|
+
* an unrecognised variant.
|
|
1391
|
+
*/
|
|
1392
|
+
kind: AvailabilityRequestKind | null;
|
|
1393
|
+
/**
|
|
1394
|
+
* Recruiter-pinned Fixed hourly rate (the `metadata.offeredHourlyRate`
|
|
1395
|
+
* Money shape). `null` for FLEXIBLE / MARKETPLACE_FLEXIBLE ARs — their
|
|
1396
|
+
* metadata carries no offered rate.
|
|
1397
|
+
*/
|
|
1398
|
+
fixedRate: FixedRate | null;
|
|
1399
|
+
/** Recruiter's free-text note attached to the request. */
|
|
1400
|
+
comment: string | null;
|
|
1401
|
+
/** Server-supplied creation timestamp (ISO 8601). */
|
|
1402
|
+
createdAt: string | null;
|
|
1403
|
+
/** Server-supplied last-mutation timestamp (ISO 8601). */
|
|
1404
|
+
updatedAt: string | null;
|
|
1405
|
+
/**
|
|
1406
|
+
* Timestamp the talent answered the request (confirmed / rejected).
|
|
1407
|
+
* `null` while the request is still pending.
|
|
1408
|
+
*/
|
|
1409
|
+
answeredAt: string | null;
|
|
1410
|
+
/** The job the availability request is for. */
|
|
1411
|
+
job: ApplicationJobRef | null;
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Read one `AvailabilityRequest` by id via the mobile-gateway
|
|
1415
|
+
* `AvailabilityRequest` query (#442). Sibling sub-namespace to the
|
|
1416
|
+
* top-level activity-row leaves (`list` / `show` / `stats`) and to
|
|
1417
|
+
* `interviews.show` (#439) — fetches the rich availability-request
|
|
1418
|
+
* detail once the user knows the id from `applications show
|
|
1419
|
+
* <activityId>` (the `Availability request: <id>` line). The id is the
|
|
1420
|
+
* same `AvailabilityRequest.id` the #411 `confirm` / `reject` write-side
|
|
1421
|
+
* ops accept.
|
|
1422
|
+
*
|
|
1423
|
+
* @throws `ApplicationsError("NOT_FOUND")` when the id doesn't resolve
|
|
1424
|
+
* to an availability request the signed-in user can see, OR when the
|
|
1425
|
+
* wire surfaces a `NOT_FOUND_MESSAGE_PATTERN`-matched GraphQL error
|
|
1426
|
+
* (`Record not found` / `Invalid ID` / Relay `Node id ... resolves to`).
|
|
1427
|
+
* @throws `ApplicationsError("NO_VIEWER")` when the session is valid
|
|
1428
|
+
* but no viewer is bound.
|
|
1429
|
+
*/
|
|
1430
|
+
declare function availabilityRequestsShow(token: string, id: string): Promise<AvailabilityRequestDetail>;
|
|
1431
|
+
/**
|
|
1432
|
+
* `applications.availabilityRequests.*` sub-namespace. Read-only leaf
|
|
1433
|
+
* for availability-request-detail access — sibling to `interviews.*`
|
|
1434
|
+
* (#439 / #440) and to the top-level activity-row leaves. The plural
|
|
1435
|
+
* `availabilityRequests` form matches `interviews` / `payouts` /
|
|
1436
|
+
* `methods` for collection-style namespaces; the #411 write-side ops
|
|
1437
|
+
* (`confirm` / `reject` / `rejectReasons`) stay top-level flat exports
|
|
1438
|
+
* (they predate the sub-namespace convention).
|
|
1439
|
+
*/
|
|
1440
|
+
export declare const availabilityRequests: {
|
|
1441
|
+
show: typeof availabilityRequestsShow;
|
|
1442
|
+
};
|
|
539
1443
|
//# sourceMappingURL=index.d.ts.map
|