@saasicat/spec 1.0.0-rc.24 → 1.0.0-rc.26
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/admin-api.openapi.yaml +888 -2
- package/package.json +1 -1
- package/prisma-fragments/05-bundle.prisma +4 -3
- package/prisma-fragments/08-subscription-contract.prisma +9 -0
- package/prisma-fragments/09-pending-registration.prisma +6 -0
- package/prisma-fragments/11-subscription-bundle.prisma +12 -2
- package/prisma-fragments/13-subscriber.prisma +82 -8
- package/prisma-fragments/15-subscriber-ledger.prisma +2 -1
- package/prisma-fragments/17-subscription-notice.prisma +5 -2
- package/prisma-fragments/19-bundle-version-retirement.prisma +44 -0
- package/prisma-fragments/20-subscription-invoice.prisma +145 -0
- package/prisma-fragments/21-feature-withdrawal.prisma +56 -0
- package/prisma-fragments/22-subscription-invoice-archive.prisma +34 -0
- package/prisma-fragments/README.md +26 -20
- package/schemas/admin-manifest.schema.json +2 -1
- package/schemas/plan-catalog.schema.json +57 -2
- package/schemas/subscriber-ledger.schema.json +4 -2
- package/sql/1.0-a-correction-carries-its-order.postgres.sql +101 -0
- package/sql/1.0-a-feature-is-withdrawn.postgres.sql +49 -0
- package/sql/1.0-a-sign-up-keeps-its-vat-id-check.postgres.sql +38 -0
- package/sql/1.0-a-subscriber-has-a-tax-origin.postgres.sql +113 -0
- package/sql/1.0-an-add-on-retirement-is-announced.postgres.sql +44 -0
- package/sql/1.0-an-add-on-switch-waits-for-its-term.postgres.sql +52 -0
- package/sql/1.0-an-invoice-document-is-archived.postgres.sql +123 -0
- package/sql/1.0-an-invoice-is-issued.postgres.sql +171 -0
- package/sql/constraints.postgres.sql +17 -0
- package/sql/reference-schema.postgres.sql +250 -1
package/admin-api.openapi.yaml
CHANGED
|
@@ -29,7 +29,7 @@ openapi: 3.1.0
|
|
|
29
29
|
|
|
30
30
|
info:
|
|
31
31
|
title: SaaS Platform SuperAdmin API
|
|
32
|
-
version: 1.0.0-rc.
|
|
32
|
+
version: 1.0.0-rc.26
|
|
33
33
|
description: |
|
|
34
34
|
Read and write operations for platform administration:
|
|
35
35
|
tenants, users, subscriptions, promo codes, audit log,
|
|
@@ -387,6 +387,240 @@ paths:
|
|
|
387
387
|
'404':
|
|
388
388
|
description: No tenant with this slug (`TENANT_NOT_FOUND`)
|
|
389
389
|
|
|
390
|
+
/invoices/{id}/document:
|
|
391
|
+
parameters:
|
|
392
|
+
- name: id
|
|
393
|
+
in: path
|
|
394
|
+
required: true
|
|
395
|
+
description: The invoice's id
|
|
396
|
+
schema: { type: string }
|
|
397
|
+
get:
|
|
398
|
+
tags: [subscriptions]
|
|
399
|
+
summary: The document an invoice was issued as
|
|
400
|
+
description: >-
|
|
401
|
+
Served where the platform keeps invoices
|
|
402
|
+
(`tenantBilling.chargeJournal.invoices`) and shows tenants
|
|
403
|
+
(`adminResources`); the manifest announces it as
|
|
404
|
+
`invoices.read`. Answers the file archived for the invoice,
|
|
405
|
+
checked against the checksum recorded when it was rendered —
|
|
406
|
+
never a new rendering. Its media type is the one the renderer
|
|
407
|
+
gave, a PDF for a ZUGFeRD invoice.
|
|
408
|
+
responses:
|
|
409
|
+
'200':
|
|
410
|
+
description: The archived file, as an attachment
|
|
411
|
+
headers:
|
|
412
|
+
Content-Disposition:
|
|
413
|
+
description: >-
|
|
414
|
+
`attachment; filename="…"`, the renderer's file
|
|
415
|
+
name kept to letters, digits, `.`, `_` and `-`
|
|
416
|
+
schema: { type: string }
|
|
417
|
+
content:
|
|
418
|
+
application/pdf:
|
|
419
|
+
schema: { type: string, format: binary }
|
|
420
|
+
'404':
|
|
421
|
+
description: No invoice with this id (`SUBSCRIPTION_INVOICE_NOT_FOUND`)
|
|
422
|
+
'409':
|
|
423
|
+
description: >-
|
|
424
|
+
The invoice still waits for its document
|
|
425
|
+
(`SUBSCRIPTION_INVOICE_DOCUMENT_NOT_ARCHIVED`), or its
|
|
426
|
+
archived file does not match the recorded checksum and
|
|
427
|
+
is not handed out (`SUBSCRIPTION_INVOICE_DOCUMENT_MISMATCH`)
|
|
428
|
+
|
|
429
|
+
/tenants/{slug}/subscriber:
|
|
430
|
+
parameters:
|
|
431
|
+
- $ref: '#/components/parameters/TenantSlug'
|
|
432
|
+
get:
|
|
433
|
+
tags: [subscriptions]
|
|
434
|
+
summary: The tenant's subscriber, its tax details and what holds its next contract back
|
|
435
|
+
description: >-
|
|
436
|
+
Served where the platform keeps subscribers and shows tenants
|
|
437
|
+
(`adminResources`); the manifest announces it as
|
|
438
|
+
`subscribers.read`. The standing is computed when it is read,
|
|
439
|
+
and only where a tax adapter decides; elsewhere `readiness` is
|
|
440
|
+
null.
|
|
441
|
+
responses:
|
|
442
|
+
'200':
|
|
443
|
+
description: The subscriber, or none
|
|
444
|
+
content:
|
|
445
|
+
application/json:
|
|
446
|
+
schema: { $ref: '#/components/schemas/AdminTenantSubscriber' }
|
|
447
|
+
'404':
|
|
448
|
+
description: No tenant with this slug (`TENANT_NOT_FOUND`)
|
|
449
|
+
|
|
450
|
+
/tenants/{slug}/subscriber/history:
|
|
451
|
+
parameters:
|
|
452
|
+
- $ref: '#/components/parameters/TenantSlug'
|
|
453
|
+
get:
|
|
454
|
+
tags: [subscriptions]
|
|
455
|
+
summary: Every correction, change of country or business status, and check of the subscriber, the latest first
|
|
456
|
+
description: >-
|
|
457
|
+
Served beside `/tenants/{slug}/subscriber`; the manifest
|
|
458
|
+
announces it as `subscribers.correct`. A correction that gives
|
|
459
|
+
another VAT number is named once, as the correction it was. Empty
|
|
460
|
+
for a tenant without a subscriber.
|
|
461
|
+
responses:
|
|
462
|
+
'200':
|
|
463
|
+
description: The history
|
|
464
|
+
content:
|
|
465
|
+
application/json:
|
|
466
|
+
schema:
|
|
467
|
+
type: object
|
|
468
|
+
required: [entries]
|
|
469
|
+
properties:
|
|
470
|
+
entries:
|
|
471
|
+
type: array
|
|
472
|
+
items:
|
|
473
|
+
$ref: '#/components/schemas/AdminSubscriberHistoryEntry'
|
|
474
|
+
'404':
|
|
475
|
+
description: No tenant with this slug (`TENANT_NOT_FOUND`)
|
|
476
|
+
|
|
477
|
+
/tenants/{slug}/subscriber/identity:
|
|
478
|
+
parameters:
|
|
479
|
+
- $ref: '#/components/parameters/TenantSlug'
|
|
480
|
+
post:
|
|
481
|
+
tags: [subscriptions]
|
|
482
|
+
summary: Correct the legal identity of the tenant's subscriber
|
|
483
|
+
description: >-
|
|
484
|
+
A correction of the same legal entity — a field left out keeps
|
|
485
|
+
its value, `null` clears a tax identifier — recorded with the
|
|
486
|
+
values it replaced, the reason and who made it. `kind` is the
|
|
487
|
+
operator's declaration: a takeover by another entity is refused
|
|
488
|
+
(`SUBSCRIBER_TAKEOVER_IS_A_TRANSFER`). Where a tax adapter
|
|
489
|
+
decides and the correction gives another VAT number, that
|
|
490
|
+
number is checked right after and the check recorded, whatever
|
|
491
|
+
it found; the answer says how it went.
|
|
492
|
+
x-mfa-required: true
|
|
493
|
+
requestBody:
|
|
494
|
+
required: true
|
|
495
|
+
content:
|
|
496
|
+
application/json:
|
|
497
|
+
schema:
|
|
498
|
+
type: object
|
|
499
|
+
required: [kind, reason]
|
|
500
|
+
properties:
|
|
501
|
+
kind: { type: string, enum: [correction, takeover] }
|
|
502
|
+
legalName: { type: string }
|
|
503
|
+
vatId: { type: string, nullable: true }
|
|
504
|
+
taxNumber: { type: string, nullable: true }
|
|
505
|
+
reason: { type: string, maxLength: 500 }
|
|
506
|
+
responses:
|
|
507
|
+
'200':
|
|
508
|
+
description: The subscriber as it now stands, and the check its new number got
|
|
509
|
+
content:
|
|
510
|
+
application/json:
|
|
511
|
+
schema: { $ref: '#/components/schemas/AdminSubscriberCorrected' }
|
|
512
|
+
'404':
|
|
513
|
+
description: No tenant with this slug (`TENANT_NOT_FOUND`)
|
|
514
|
+
'409':
|
|
515
|
+
description: The tenant has no subscriber (`SUBSCRIBER_REQUIRED`)
|
|
516
|
+
'422':
|
|
517
|
+
description: >-
|
|
518
|
+
A takeover, no reason, or a correction that changes
|
|
519
|
+
nothing (`SUBSCRIBER_TAKEOVER_IS_A_TRANSFER`,
|
|
520
|
+
`SUBSCRIBER_CORRECTION_REASON_REQUIRED`,
|
|
521
|
+
`SUBSCRIBER_CORRECTION_CHANGES_NOTHING`)
|
|
522
|
+
|
|
523
|
+
/tenants/{slug}/subscriber/business-status:
|
|
524
|
+
parameters:
|
|
525
|
+
- $ref: '#/components/parameters/TenantSlug'
|
|
526
|
+
post:
|
|
527
|
+
tags: [subscriptions]
|
|
528
|
+
summary: Record whether the tenant's subscriber acts as a business, and why
|
|
529
|
+
description: >-
|
|
530
|
+
Recorded as a change of the tax origin with its reason and who
|
|
531
|
+
made it; it applies from the next contract. Setting the status it
|
|
532
|
+
has records nothing.
|
|
533
|
+
x-mfa-required: true
|
|
534
|
+
requestBody:
|
|
535
|
+
required: true
|
|
536
|
+
content:
|
|
537
|
+
application/json:
|
|
538
|
+
schema:
|
|
539
|
+
type: object
|
|
540
|
+
required: [business, reason]
|
|
541
|
+
properties:
|
|
542
|
+
business: { type: boolean, nullable: true }
|
|
543
|
+
reason: { type: string, maxLength: 500 }
|
|
544
|
+
responses:
|
|
545
|
+
'200':
|
|
546
|
+
description: The subscriber as it now stands
|
|
547
|
+
content:
|
|
548
|
+
application/json:
|
|
549
|
+
schema: { $ref: '#/components/schemas/AdminSubscriberCorrected' }
|
|
550
|
+
'404':
|
|
551
|
+
description: No tenant with this slug (`TENANT_NOT_FOUND`)
|
|
552
|
+
'409':
|
|
553
|
+
description: The tenant has no subscriber (`SUBSCRIBER_REQUIRED`)
|
|
554
|
+
'422':
|
|
555
|
+
description: No reason (`SUBSCRIBER_BUSINESS_STATUS_REASON_REQUIRED`)
|
|
556
|
+
|
|
557
|
+
/tenants/{slug}/subscriber/vat-id-check:
|
|
558
|
+
parameters:
|
|
559
|
+
- $ref: '#/components/parameters/TenantSlug'
|
|
560
|
+
post:
|
|
561
|
+
tags: [subscriptions]
|
|
562
|
+
summary: Check the VAT number the tenant's subscriber holds, again
|
|
563
|
+
description: >-
|
|
564
|
+
Asks the service the tax adapter names and records a completed
|
|
565
|
+
check, valid or not; a check that does not complete records
|
|
566
|
+
nothing and says why. No second factor: nothing is entered, and
|
|
567
|
+
the answer is the service's.
|
|
568
|
+
responses:
|
|
569
|
+
'200':
|
|
570
|
+
description: The subscriber as it now stands, and what the check found
|
|
571
|
+
content:
|
|
572
|
+
application/json:
|
|
573
|
+
schema: { $ref: '#/components/schemas/AdminSubscriberCorrected' }
|
|
574
|
+
'404':
|
|
575
|
+
description: No tenant with this slug (`TENANT_NOT_FOUND`)
|
|
576
|
+
'409':
|
|
577
|
+
description: >-
|
|
578
|
+
The tenant has no subscriber, or no tax adapter names a
|
|
579
|
+
service (`SUBSCRIBER_REQUIRED`, `TAX_VAT_ID_CHECK_NOT_AVAILABLE`)
|
|
580
|
+
'422':
|
|
581
|
+
description: The subscriber holds no VAT number (`SUBSCRIBER_VAT_ID_MISSING`)
|
|
582
|
+
|
|
583
|
+
/subscribers/attention:
|
|
584
|
+
get:
|
|
585
|
+
tags: [subscriptions]
|
|
586
|
+
summary: Which of these tenants hold their subscriber back from its next contract
|
|
587
|
+
description: >-
|
|
588
|
+
Served beside `/tenants/{slug}/subscriber`; the manifest
|
|
589
|
+
announces `subscribers.attention` only where a tax adapter
|
|
590
|
+
decides, and without one the answer is always empty. A tenant
|
|
591
|
+
whose subscriber is ready, and one without a subscriber, are
|
|
592
|
+
left out.
|
|
593
|
+
parameters:
|
|
594
|
+
- name: tenantId
|
|
595
|
+
in: query
|
|
596
|
+
description: The tenants of the page shown; repeat the parameter for each.
|
|
597
|
+
schema:
|
|
598
|
+
type: array
|
|
599
|
+
maxItems: 200
|
|
600
|
+
items: { type: string, minLength: 1 }
|
|
601
|
+
style: form
|
|
602
|
+
explode: true
|
|
603
|
+
responses:
|
|
604
|
+
'200':
|
|
605
|
+
description: The tenants held back, each with why
|
|
606
|
+
content:
|
|
607
|
+
application/json:
|
|
608
|
+
schema:
|
|
609
|
+
type: object
|
|
610
|
+
required: [attention]
|
|
611
|
+
properties:
|
|
612
|
+
attention:
|
|
613
|
+
type: array
|
|
614
|
+
items:
|
|
615
|
+
type: object
|
|
616
|
+
required: [tenantId, readiness]
|
|
617
|
+
properties:
|
|
618
|
+
tenantId: { type: string }
|
|
619
|
+
readiness:
|
|
620
|
+
$ref: '#/components/schemas/SubscriberReadiness'
|
|
621
|
+
'400':
|
|
622
|
+
description: More than 200 tenants, or an empty tenant id
|
|
623
|
+
|
|
390
624
|
# ────────────────────────────────────────────────────────
|
|
391
625
|
# Users
|
|
392
626
|
# ────────────────────────────────────────────────────────
|
|
@@ -812,8 +1046,9 @@ paths:
|
|
|
812
1046
|
id: { type: string }
|
|
813
1047
|
tenant:
|
|
814
1048
|
type: object
|
|
815
|
-
required: [slug, name]
|
|
1049
|
+
required: [id, slug, name]
|
|
816
1050
|
properties:
|
|
1051
|
+
id: { type: string }
|
|
817
1052
|
slug: { type: string }
|
|
818
1053
|
name: { type: string }
|
|
819
1054
|
plan: { type: string }
|
|
@@ -1084,6 +1319,203 @@ paths:
|
|
|
1084
1319
|
type: array
|
|
1085
1320
|
items: { $ref: '#/components/schemas/VersionRetirement' }
|
|
1086
1321
|
|
|
1322
|
+
# Served where the manifest carries the capability `bundleVersions.retire`. The bookings
|
|
1323
|
+
# on an add-on version no longer on sale continue on a version of the same add-on on
|
|
1324
|
+
# sale, each at the first end of its own period at least three calendar months after
|
|
1325
|
+
# its notice reached the subscriber, and may be cancelled without their minimum term
|
|
1326
|
+
# until then. Where the operator's terms are not confirmed to allow it, both routes
|
|
1327
|
+
# refuse with `RETIREMENT_TERMS_NOT_CONFIRMED` before reading anything.
|
|
1328
|
+
|
|
1329
|
+
/catalog/bundle-versions/{id}/retirement:
|
|
1330
|
+
parameters: [{ name: id, in: path, required: true, schema: { type: string } }]
|
|
1331
|
+
get:
|
|
1332
|
+
tags: [catalog]
|
|
1333
|
+
summary: What retiring the add-on version for its running bookings would do now
|
|
1334
|
+
parameters:
|
|
1335
|
+
- name: replacement
|
|
1336
|
+
in: query
|
|
1337
|
+
required: true
|
|
1338
|
+
description: The version of the same add-on the bookings continue on
|
|
1339
|
+
schema: { type: string, format: uuid }
|
|
1340
|
+
responses:
|
|
1341
|
+
'200':
|
|
1342
|
+
description: >-
|
|
1343
|
+
Which bookings it reaches and when, which it does not and why, and every
|
|
1344
|
+
blocker the announcement would refuse with
|
|
1345
|
+
content:
|
|
1346
|
+
application/json:
|
|
1347
|
+
schema: { $ref: '#/components/schemas/BundleRetirementPreview' }
|
|
1348
|
+
'404':
|
|
1349
|
+
description: Either version does not exist (`BUNDLE_VERSION_NOT_FOUND`)
|
|
1350
|
+
'422':
|
|
1351
|
+
description: >-
|
|
1352
|
+
The terms are not confirmed (`RETIREMENT_TERMS_NOT_CONFIRMED`), or the
|
|
1353
|
+
replacement is the version itself (`RETIREMENT_REPLACEMENT_IS_RETIRED`)
|
|
1354
|
+
post:
|
|
1355
|
+
tags: [catalog]
|
|
1356
|
+
summary: Announce the add-on retirement to every booking it reaches
|
|
1357
|
+
description: >-
|
|
1358
|
+
The announcement and one notice per booking are recorded in one transaction,
|
|
1359
|
+
then handed to the application's `SubscriptionNoticePort` as
|
|
1360
|
+
`bundle-version-retired`; a notice that cannot be sent now is sent by the next
|
|
1361
|
+
run. Audited as BUNDLE_VERSION_RETIRE.
|
|
1362
|
+
x-mfa-required: true
|
|
1363
|
+
requestBody:
|
|
1364
|
+
required: true
|
|
1365
|
+
content:
|
|
1366
|
+
application/json:
|
|
1367
|
+
schema: { $ref: '#/components/schemas/BundleRetirementAnnouncement' }
|
|
1368
|
+
responses:
|
|
1369
|
+
'201':
|
|
1370
|
+
description: Announced
|
|
1371
|
+
content:
|
|
1372
|
+
application/json:
|
|
1373
|
+
schema: { $ref: '#/components/schemas/BundleRetirementAnnounced' }
|
|
1374
|
+
'409':
|
|
1375
|
+
description: >-
|
|
1376
|
+
The bookings it reaches are no longer the ones named
|
|
1377
|
+
(`RETIREMENT_PREVIEW_CHANGED`); the body carries the preview as it stands
|
|
1378
|
+
'422':
|
|
1379
|
+
description: >-
|
|
1380
|
+
The first blocker the preview reports (`BUNDLE_RETIREMENT_*`,
|
|
1381
|
+
`RETIREMENT_WITHIN_TWELVE_MONTHS`), with every blocker beside it
|
|
1382
|
+
|
|
1383
|
+
/catalog/bundle-version-retirements:
|
|
1384
|
+
get:
|
|
1385
|
+
tags: [catalog]
|
|
1386
|
+
summary: Every add-on retirement announced, the most recent first
|
|
1387
|
+
responses:
|
|
1388
|
+
'200':
|
|
1389
|
+
description: List, each with how far it has come over the bookings it reached
|
|
1390
|
+
content:
|
|
1391
|
+
application/json:
|
|
1392
|
+
schema:
|
|
1393
|
+
type: array
|
|
1394
|
+
items: { $ref: '#/components/schemas/BundleVersionRetirement' }
|
|
1395
|
+
|
|
1396
|
+
# ── Feature withdrawals ──
|
|
1397
|
+
#
|
|
1398
|
+
# Served where the manifest carries the capability `features.withdraw`: where the
|
|
1399
|
+
# installation can list everybody a withdrawal reaches. A feature withdrawn for a reason
|
|
1400
|
+
# outside the platform — an external service stopped, a law changed — is granted to
|
|
1401
|
+
# nobody from the date named until the withdrawal is lifted. The subscriptions holding
|
|
1402
|
+
# it when it is announced are told at once; each line is reduced by the amount named
|
|
1403
|
+
# for its plan or add-on and rhythm, and each may end at once while it is withdrawn.
|
|
1404
|
+
|
|
1405
|
+
/feature-withdrawals:
|
|
1406
|
+
get:
|
|
1407
|
+
tags: [catalog]
|
|
1408
|
+
summary: Every withdrawal, the most recently announced first
|
|
1409
|
+
responses:
|
|
1410
|
+
'200':
|
|
1411
|
+
description: List, each with how many it reached, told and ended at once
|
|
1412
|
+
content:
|
|
1413
|
+
application/json:
|
|
1414
|
+
schema:
|
|
1415
|
+
type: array
|
|
1416
|
+
items: { $ref: '#/components/schemas/FeatureWithdrawal' }
|
|
1417
|
+
post:
|
|
1418
|
+
tags: [catalog]
|
|
1419
|
+
summary: Withdraw a feature from every subscription that holds it
|
|
1420
|
+
description: >-
|
|
1421
|
+
The withdrawal and one notice per subscription are recorded in one transaction,
|
|
1422
|
+
then handed to the application's `SubscriptionNoticePort` as `feature-withdrawn`;
|
|
1423
|
+
a notice that cannot be sent now is sent by the next run. The reductions are
|
|
1424
|
+
written into each subscription's contract. Audited as FEATURE_WITHDRAW.
|
|
1425
|
+
x-mfa-required: true
|
|
1426
|
+
requestBody:
|
|
1427
|
+
required: true
|
|
1428
|
+
content:
|
|
1429
|
+
application/json:
|
|
1430
|
+
schema: { $ref: '#/components/schemas/FeatureWithdrawalAnnouncement' }
|
|
1431
|
+
responses:
|
|
1432
|
+
'201':
|
|
1433
|
+
description: Announced
|
|
1434
|
+
content:
|
|
1435
|
+
application/json:
|
|
1436
|
+
schema: { $ref: '#/components/schemas/FeatureWithdrawalAnnounced' }
|
|
1437
|
+
'404':
|
|
1438
|
+
description: >-
|
|
1439
|
+
Not offered here: the stores cannot list everybody a withdrawal reaches
|
|
1440
|
+
(`FEATURE_WITHDRAWAL_UNAVAILABLE`)
|
|
1441
|
+
'409':
|
|
1442
|
+
description: >-
|
|
1443
|
+
The subscriptions it reaches are no longer the ones named
|
|
1444
|
+
(`FEATURE_WITHDRAWAL_PREVIEW_CHANGED`, with the preview as it stands), or
|
|
1445
|
+
another withdrawal of the feature landed first (`FEATURE_WITHDRAWAL_OPEN`)
|
|
1446
|
+
'422':
|
|
1447
|
+
description: >-
|
|
1448
|
+
An unknown feature (`FEATURE_WITHDRAWAL_FEATURE_UNKNOWN`), a date already
|
|
1449
|
+
past (`FEATURE_WITHDRAWAL_DATE_IN_PAST`), a reduction that names nothing it
|
|
1450
|
+
reaches, is named twice or exceeds the lowest price it reduces
|
|
1451
|
+
(`FEATURE_WITHDRAWAL_REDUCTION_*`), or the first blocker the preview reports
|
|
1452
|
+
|
|
1453
|
+
/feature-withdrawals/preview:
|
|
1454
|
+
get:
|
|
1455
|
+
tags: [catalog]
|
|
1456
|
+
summary: What withdrawing the feature from the date would do now
|
|
1457
|
+
parameters:
|
|
1458
|
+
- name: featureKey
|
|
1459
|
+
in: query
|
|
1460
|
+
required: true
|
|
1461
|
+
schema: { type: string }
|
|
1462
|
+
- name: effectiveFrom
|
|
1463
|
+
in: query
|
|
1464
|
+
required: false
|
|
1465
|
+
description: ISO-8601; now where left out
|
|
1466
|
+
schema: { type: string, format: date-time }
|
|
1467
|
+
responses:
|
|
1468
|
+
'200':
|
|
1469
|
+
description: >-
|
|
1470
|
+
Whom it reaches with which lines, whom it does not and why, the plans and
|
|
1471
|
+
add-ons a reduction may be named for, and every blocker
|
|
1472
|
+
content:
|
|
1473
|
+
application/json:
|
|
1474
|
+
schema: { $ref: '#/components/schemas/FeatureWithdrawalPreview' }
|
|
1475
|
+
'404':
|
|
1476
|
+
description: Not offered here (`FEATURE_WITHDRAWAL_UNAVAILABLE`)
|
|
1477
|
+
'422':
|
|
1478
|
+
description: >-
|
|
1479
|
+
An unknown feature (`FEATURE_WITHDRAWAL_FEATURE_UNKNOWN`), or a date already
|
|
1480
|
+
past (`FEATURE_WITHDRAWAL_DATE_IN_PAST`)
|
|
1481
|
+
|
|
1482
|
+
/feature-withdrawals/{id}/lift:
|
|
1483
|
+
parameters: [{ name: id, in: path, required: true, schema: { type: string } }]
|
|
1484
|
+
post:
|
|
1485
|
+
tags: [catalog]
|
|
1486
|
+
summary: Lift a withdrawal from a date
|
|
1487
|
+
description: >-
|
|
1488
|
+
From the date the feature is granted again, and the reduction and the right to end
|
|
1489
|
+
at once end; every subscription it reached that still runs is told as
|
|
1490
|
+
`feature-withdrawal-lifted`. Audited as FEATURE_WITHDRAWAL_LIFT.
|
|
1491
|
+
x-mfa-required: true
|
|
1492
|
+
requestBody:
|
|
1493
|
+
required: true
|
|
1494
|
+
content:
|
|
1495
|
+
application/json:
|
|
1496
|
+
schema:
|
|
1497
|
+
type: object
|
|
1498
|
+
properties:
|
|
1499
|
+
liftedFrom:
|
|
1500
|
+
type: string
|
|
1501
|
+
format: date-time
|
|
1502
|
+
description: ISO-8601; now where left out
|
|
1503
|
+
responses:
|
|
1504
|
+
'201':
|
|
1505
|
+
description: Lifted
|
|
1506
|
+
content:
|
|
1507
|
+
application/json:
|
|
1508
|
+
schema: { $ref: '#/components/schemas/FeatureWithdrawalLifted' }
|
|
1509
|
+
'404':
|
|
1510
|
+
description: No withdrawal has that id (`FEATURE_WITHDRAWAL_NOT_FOUND`)
|
|
1511
|
+
'409':
|
|
1512
|
+
description: >-
|
|
1513
|
+
Lifted already (`FEATURE_WITHDRAWAL_ALREADY_LIFTED`, with its date), or nobody
|
|
1514
|
+
it reaches told of it yet, telling them having failed just now
|
|
1515
|
+
(`FEATURE_WITHDRAWAL_NOT_TOLD_YET`)
|
|
1516
|
+
'422':
|
|
1517
|
+
description: A date already past (`FEATURE_WITHDRAWAL_LIFT_IN_PAST`)
|
|
1518
|
+
|
|
1087
1519
|
# ── Bundles ──
|
|
1088
1520
|
/catalog/bundles:
|
|
1089
1521
|
get:
|
|
@@ -2114,6 +2546,327 @@ components:
|
|
|
2114
2546
|
told: { type: integer, description: 'Notices sent at once' }
|
|
2115
2547
|
failed: { type: integer, description: 'Notices the next run sends' }
|
|
2116
2548
|
|
|
2549
|
+
FeatureWithdrawalReduction:
|
|
2550
|
+
type: object
|
|
2551
|
+
required: [kind, key, billingCycle, amountNet]
|
|
2552
|
+
properties:
|
|
2553
|
+
kind: { type: string, enum: [plan, bundle] }
|
|
2554
|
+
key: { type: string, description: 'The plan key, or the add-on key' }
|
|
2555
|
+
billingCycle: { type: string, enum: [MONTHLY, YEARLY] }
|
|
2556
|
+
amountNet:
|
|
2557
|
+
type: number
|
|
2558
|
+
description: 'Net, per whole period of the rhythm, to the cent'
|
|
2559
|
+
|
|
2560
|
+
FeatureWithdrawalAnnouncement:
|
|
2561
|
+
type: object
|
|
2562
|
+
required: [featureKey, reason, reductions, subscriptionIds]
|
|
2563
|
+
properties:
|
|
2564
|
+
featureKey: { type: string }
|
|
2565
|
+
reason: { type: string, description: 'Shown to the subscribers as written' }
|
|
2566
|
+
effectiveFrom:
|
|
2567
|
+
{ type: string, format: date-time, description: 'Now where left out' }
|
|
2568
|
+
reductions:
|
|
2569
|
+
type: array
|
|
2570
|
+
items: { $ref: '#/components/schemas/FeatureWithdrawalReduction' }
|
|
2571
|
+
subscriptionIds:
|
|
2572
|
+
type: array
|
|
2573
|
+
description: 'The subscriptions the operator was shown in the preview'
|
|
2574
|
+
items: { type: string }
|
|
2575
|
+
|
|
2576
|
+
FeatureWithdrawalRow:
|
|
2577
|
+
type: object
|
|
2578
|
+
required:
|
|
2579
|
+
[
|
|
2580
|
+
id,
|
|
2581
|
+
featureKey,
|
|
2582
|
+
reason,
|
|
2583
|
+
effectiveFrom,
|
|
2584
|
+
liftedFrom,
|
|
2585
|
+
reductions,
|
|
2586
|
+
announcedAt,
|
|
2587
|
+
announcedBy,
|
|
2588
|
+
liftedAt,
|
|
2589
|
+
liftedBy,
|
|
2590
|
+
toldAt,
|
|
2591
|
+
]
|
|
2592
|
+
properties:
|
|
2593
|
+
id: { type: string }
|
|
2594
|
+
featureKey: { type: string }
|
|
2595
|
+
reason: { type: string }
|
|
2596
|
+
effectiveFrom: { type: string, format: date-time }
|
|
2597
|
+
liftedFrom: { type: [string, 'null'], format: date-time }
|
|
2598
|
+
reductions:
|
|
2599
|
+
type: array
|
|
2600
|
+
items: { $ref: '#/components/schemas/FeatureWithdrawalReduction' }
|
|
2601
|
+
announcedAt: { type: string, format: date-time }
|
|
2602
|
+
announcedBy:
|
|
2603
|
+
{ type: string, description: 'An actor tag, as the audit log writes it' }
|
|
2604
|
+
liftedAt: { type: [string, 'null'], format: date-time }
|
|
2605
|
+
liftedBy: { type: [string, 'null'] }
|
|
2606
|
+
toldAt:
|
|
2607
|
+
type: [string, 'null']
|
|
2608
|
+
format: date-time
|
|
2609
|
+
description: >-
|
|
2610
|
+
When the subscriptions it reaches were told; null until then — the
|
|
2611
|
+
quarter-hourly run tells a withdrawal still null.
|
|
2612
|
+
|
|
2613
|
+
FeatureWithdrawal:
|
|
2614
|
+
allOf:
|
|
2615
|
+
- $ref: '#/components/schemas/FeatureWithdrawalRow'
|
|
2616
|
+
- type: object
|
|
2617
|
+
required: [featureLabel, progress]
|
|
2618
|
+
properties:
|
|
2619
|
+
featureLabel: { type: string }
|
|
2620
|
+
progress:
|
|
2621
|
+
type: object
|
|
2622
|
+
required: [reached, told, endedAtOnce]
|
|
2623
|
+
properties:
|
|
2624
|
+
reached: { type: integer, description: 'Subscriptions it reached' }
|
|
2625
|
+
told:
|
|
2626
|
+
type: integer
|
|
2627
|
+
description: 'Of those, the ones whose notice reached somebody'
|
|
2628
|
+
endedAtOnce:
|
|
2629
|
+
type: integer
|
|
2630
|
+
description: 'Subscriptions and bookings ended at once under it'
|
|
2631
|
+
|
|
2632
|
+
FeatureWithdrawalAnnounced:
|
|
2633
|
+
type: object
|
|
2634
|
+
required: [withdrawal, told, failed]
|
|
2635
|
+
properties:
|
|
2636
|
+
withdrawal: { $ref: '#/components/schemas/FeatureWithdrawalRow' }
|
|
2637
|
+
told: { type: integer, description: 'Notices sent at once' }
|
|
2638
|
+
failed: { type: integer, description: 'Notices the next run sends' }
|
|
2639
|
+
|
|
2640
|
+
FeatureWithdrawalLifted:
|
|
2641
|
+
type: object
|
|
2642
|
+
required: [withdrawal, told, failed]
|
|
2643
|
+
properties:
|
|
2644
|
+
withdrawal: { $ref: '#/components/schemas/FeatureWithdrawalRow' }
|
|
2645
|
+
told: { type: integer, description: 'Notices sent at once' }
|
|
2646
|
+
failed: { type: integer, description: 'Notices the next run sends' }
|
|
2647
|
+
|
|
2648
|
+
FeatureWithdrawalPreview:
|
|
2649
|
+
type: object
|
|
2650
|
+
required: [feature, effectiveFrom, asOf, reached, skipped, targets, blockers]
|
|
2651
|
+
properties:
|
|
2652
|
+
feature:
|
|
2653
|
+
type: object
|
|
2654
|
+
required: [key, label]
|
|
2655
|
+
properties:
|
|
2656
|
+
key: { type: string }
|
|
2657
|
+
label: { type: string }
|
|
2658
|
+
effectiveFrom: { type: string, description: 'ISO-8601' }
|
|
2659
|
+
asOf: { type: string, description: 'ISO-8601: the moment it is computed for' }
|
|
2660
|
+
reached:
|
|
2661
|
+
type: array
|
|
2662
|
+
items:
|
|
2663
|
+
type: object
|
|
2664
|
+
required: [tenantId, subscriptionId, status, lines, specialTerms]
|
|
2665
|
+
properties:
|
|
2666
|
+
tenantId: { type: string }
|
|
2667
|
+
subscriptionId: { type: string }
|
|
2668
|
+
status: { type: string }
|
|
2669
|
+
lines:
|
|
2670
|
+
type: array
|
|
2671
|
+
items:
|
|
2672
|
+
type: object
|
|
2673
|
+
required:
|
|
2674
|
+
[
|
|
2675
|
+
line,
|
|
2676
|
+
key,
|
|
2677
|
+
label,
|
|
2678
|
+
subscriptionBundleId,
|
|
2679
|
+
billingCycle,
|
|
2680
|
+
priceNet,
|
|
2681
|
+
]
|
|
2682
|
+
properties:
|
|
2683
|
+
line: { type: string, enum: [plan, bundle] }
|
|
2684
|
+
key: { type: string }
|
|
2685
|
+
label: { type: string }
|
|
2686
|
+
subscriptionBundleId: { type: [string, 'null'] }
|
|
2687
|
+
billingCycle: { type: string, enum: [MONTHLY, YEARLY] }
|
|
2688
|
+
priceNet: { type: [number, 'null'] }
|
|
2689
|
+
specialTerms:
|
|
2690
|
+
type: boolean
|
|
2691
|
+
description: 'Holds the feature through special terms, and no line'
|
|
2692
|
+
skipped:
|
|
2693
|
+
type: array
|
|
2694
|
+
items:
|
|
2695
|
+
type: object
|
|
2696
|
+
required: [tenantId, subscriptionId, reason]
|
|
2697
|
+
properties:
|
|
2698
|
+
tenantId: { type: string }
|
|
2699
|
+
subscriptionId: { type: string }
|
|
2700
|
+
reason: { type: string, enum: [ends-before] }
|
|
2701
|
+
targets:
|
|
2702
|
+
type: array
|
|
2703
|
+
description: 'Each plan and add-on in a rhythm a reduction may be named for'
|
|
2704
|
+
items:
|
|
2705
|
+
type: object
|
|
2706
|
+
required: [kind, key, label, billingCycle, lines, lowestPriceNet]
|
|
2707
|
+
properties:
|
|
2708
|
+
kind: { type: string, enum: [plan, bundle] }
|
|
2709
|
+
key: { type: string }
|
|
2710
|
+
label: { type: string }
|
|
2711
|
+
billingCycle: { type: string, enum: [MONTHLY, YEARLY] }
|
|
2712
|
+
lines: { type: integer }
|
|
2713
|
+
lowestPriceNet: { type: [number, 'null'] }
|
|
2714
|
+
blockers:
|
|
2715
|
+
type: array
|
|
2716
|
+
description: 'Empty where it may be announced as it stands'
|
|
2717
|
+
items:
|
|
2718
|
+
type: object
|
|
2719
|
+
required: [code, message, params]
|
|
2720
|
+
properties:
|
|
2721
|
+
code: { type: string, description: 'FEATURE_WITHDRAWAL_*' }
|
|
2722
|
+
message: { type: string }
|
|
2723
|
+
params: { type: object }
|
|
2724
|
+
|
|
2725
|
+
RetiredBundleVersionRef:
|
|
2726
|
+
type: object
|
|
2727
|
+
required: [bundleVersionId, bundleKey, version]
|
|
2728
|
+
properties:
|
|
2729
|
+
bundleVersionId: { type: string }
|
|
2730
|
+
bundleKey: { type: string }
|
|
2731
|
+
version: { type: integer }
|
|
2732
|
+
|
|
2733
|
+
BundleVersionSide:
|
|
2734
|
+
description: >-
|
|
2735
|
+
An add-on version as the subscribers compare it, at its own prices; each booking
|
|
2736
|
+
is told the prices beside its plan. A price of null is a rhythm it is not sold in
|
|
2737
|
+
allOf:
|
|
2738
|
+
- $ref: '#/components/schemas/RetiredBundleVersionRef'
|
|
2739
|
+
- type: object
|
|
2740
|
+
required: [label, features, quotas, monthlyNet, yearlyNet]
|
|
2741
|
+
properties:
|
|
2742
|
+
label: { type: string }
|
|
2743
|
+
features: { type: array, items: { type: string } }
|
|
2744
|
+
quotas: { type: object, additionalProperties: { type: number } }
|
|
2745
|
+
monthlyNet: { type: [number, 'null'] }
|
|
2746
|
+
yearlyNet: { type: [number, 'null'] }
|
|
2747
|
+
|
|
2748
|
+
BundleRetirementPreview:
|
|
2749
|
+
type: object
|
|
2750
|
+
required: [retired, replacement, changes, asOf, reached, skipped, blockers]
|
|
2751
|
+
properties:
|
|
2752
|
+
retired: { $ref: '#/components/schemas/BundleVersionSide' }
|
|
2753
|
+
replacement: { $ref: '#/components/schemas/BundleVersionSide' }
|
|
2754
|
+
changes:
|
|
2755
|
+
type: array
|
|
2756
|
+
description: 'Every difference at the two versions own prices'
|
|
2757
|
+
items: { type: object }
|
|
2758
|
+
asOf: { type: string, description: 'ISO-8601: the moment it is computed for' }
|
|
2759
|
+
reached:
|
|
2760
|
+
type: array
|
|
2761
|
+
items:
|
|
2762
|
+
type: object
|
|
2763
|
+
required:
|
|
2764
|
+
[
|
|
2765
|
+
tenantId,
|
|
2766
|
+
subscriptionId,
|
|
2767
|
+
subscriptionBundleId,
|
|
2768
|
+
planKey,
|
|
2769
|
+
planCycle,
|
|
2770
|
+
billingCycle,
|
|
2771
|
+
effectiveAt,
|
|
2772
|
+
lastDayToCancel,
|
|
2773
|
+
reachedRecently,
|
|
2774
|
+
]
|
|
2775
|
+
properties:
|
|
2776
|
+
tenantId: { type: string }
|
|
2777
|
+
subscriptionId: { type: string }
|
|
2778
|
+
subscriptionBundleId: { type: string }
|
|
2779
|
+
planKey: { type: string, description: 'The plan beside it at the date' }
|
|
2780
|
+
planCycle: { type: string }
|
|
2781
|
+
billingCycle: { type: string, description: 'The booking rhythm' }
|
|
2782
|
+
effectiveAt:
|
|
2783
|
+
{ type: string, description: 'ISO-8601: an end of its period' }
|
|
2784
|
+
lastDayToCancel:
|
|
2785
|
+
{ type: string, description: 'ISO date, UTC: the day before' }
|
|
2786
|
+
reachedRecently:
|
|
2787
|
+
{
|
|
2788
|
+
type: boolean,
|
|
2789
|
+
description: 'Its subscription was reached by a retirement within twelve months',
|
|
2790
|
+
}
|
|
2791
|
+
skipped:
|
|
2792
|
+
type: array
|
|
2793
|
+
items:
|
|
2794
|
+
type: object
|
|
2795
|
+
required: [tenantId, subscriptionId, subscriptionBundleId, reason]
|
|
2796
|
+
properties:
|
|
2797
|
+
tenantId: { type: string }
|
|
2798
|
+
subscriptionId: { type: string }
|
|
2799
|
+
subscriptionBundleId: { type: string }
|
|
2800
|
+
reason:
|
|
2801
|
+
{
|
|
2802
|
+
type: string,
|
|
2803
|
+
enum:
|
|
2804
|
+
[
|
|
2805
|
+
ended,
|
|
2806
|
+
cancelled-before,
|
|
2807
|
+
changes-before,
|
|
2808
|
+
no-term,
|
|
2809
|
+
already-told,
|
|
2810
|
+
],
|
|
2811
|
+
}
|
|
2812
|
+
blockers:
|
|
2813
|
+
type: array
|
|
2814
|
+
description: 'Empty where it may be announced as it stands'
|
|
2815
|
+
items:
|
|
2816
|
+
type: object
|
|
2817
|
+
required: [code, message, params]
|
|
2818
|
+
properties:
|
|
2819
|
+
code: { type: string, description: 'BUNDLE_RETIREMENT_*, RETIREMENT_*' }
|
|
2820
|
+
message: { type: string }
|
|
2821
|
+
params: { type: object }
|
|
2822
|
+
|
|
2823
|
+
BundleRetirementAnnouncement:
|
|
2824
|
+
type: object
|
|
2825
|
+
required: [replacementBundleVersionId, subscriptionBundleIds]
|
|
2826
|
+
properties:
|
|
2827
|
+
replacementBundleVersionId: { type: string, format: uuid }
|
|
2828
|
+
subscriptionBundleIds:
|
|
2829
|
+
type: array
|
|
2830
|
+
description: 'The bookings the operator was shown in the preview'
|
|
2831
|
+
items: { type: string }
|
|
2832
|
+
|
|
2833
|
+
BundleVersionRetirementRecord:
|
|
2834
|
+
type: object
|
|
2835
|
+
required: [id, retired, replacement, announcedAt, announcedBy]
|
|
2836
|
+
properties:
|
|
2837
|
+
id: { type: string }
|
|
2838
|
+
retired: { $ref: '#/components/schemas/RetiredBundleVersionRef' }
|
|
2839
|
+
replacement: { $ref: '#/components/schemas/RetiredBundleVersionRef' }
|
|
2840
|
+
announcedAt: { type: string }
|
|
2841
|
+
announcedBy: { type: string }
|
|
2842
|
+
|
|
2843
|
+
BundleVersionRetirement:
|
|
2844
|
+
description: 'An add-on announcement as the list answers it, with how far it has come'
|
|
2845
|
+
allOf:
|
|
2846
|
+
- $ref: '#/components/schemas/BundleVersionRetirementRecord'
|
|
2847
|
+
- type: object
|
|
2848
|
+
required: [progress]
|
|
2849
|
+
properties:
|
|
2850
|
+
progress:
|
|
2851
|
+
type: object
|
|
2852
|
+
description: 'Counted over the bookings it reached'
|
|
2853
|
+
required: [moved, waiting, overdue, ended, notTold, reminded]
|
|
2854
|
+
properties:
|
|
2855
|
+
moved: { type: integer }
|
|
2856
|
+
waiting: { type: integer }
|
|
2857
|
+
overdue: { type: integer }
|
|
2858
|
+
ended: { type: integer }
|
|
2859
|
+
notTold: { type: integer }
|
|
2860
|
+
reminded: { type: integer }
|
|
2861
|
+
|
|
2862
|
+
BundleRetirementAnnounced:
|
|
2863
|
+
type: object
|
|
2864
|
+
required: [retirement, told, failed]
|
|
2865
|
+
properties:
|
|
2866
|
+
retirement: { $ref: '#/components/schemas/BundleVersionRetirementRecord' }
|
|
2867
|
+
told: { type: integer, description: 'Notices sent at once' }
|
|
2868
|
+
failed: { type: integer, description: 'Notices the next run sends' }
|
|
2869
|
+
|
|
2117
2870
|
CatalogMarketingProjectionUpdate:
|
|
2118
2871
|
type: object
|
|
2119
2872
|
description: 'Partial update of a marketing projection'
|
|
@@ -2432,6 +3185,139 @@ components:
|
|
|
2432
3185
|
contract was concluded; null where that line
|
|
2433
3186
|
cannot be read.
|
|
2434
3187
|
|
|
3188
|
+
SubscriberReadiness:
|
|
3189
|
+
type: object
|
|
3190
|
+
description: >-
|
|
3191
|
+
Whether a subscriber can be given its next contract where a tax
|
|
3192
|
+
adapter decides: the empty fields of the address an invoice
|
|
3193
|
+
names, and the adapter's sentence where it supports no
|
|
3194
|
+
treatment for the subscriber as it stands.
|
|
3195
|
+
required: [ready, missing, taxRefusal]
|
|
3196
|
+
properties:
|
|
3197
|
+
ready: { type: boolean }
|
|
3198
|
+
missing:
|
|
3199
|
+
type: array
|
|
3200
|
+
items:
|
|
3201
|
+
type: string
|
|
3202
|
+
enum: [addressLine1, postalCode, city, country]
|
|
3203
|
+
taxRefusal:
|
|
3204
|
+
type: string
|
|
3205
|
+
nullable: true
|
|
3206
|
+
|
|
3207
|
+
AdminTenantSubscriber:
|
|
3208
|
+
type: object
|
|
3209
|
+
required: [subscriber, readiness]
|
|
3210
|
+
properties:
|
|
3211
|
+
subscriber:
|
|
3212
|
+
type: object
|
|
3213
|
+
nullable: true
|
|
3214
|
+
description: Null for a tenant that has no subscriber.
|
|
3215
|
+
required:
|
|
3216
|
+
[
|
|
3217
|
+
id,
|
|
3218
|
+
customerNumber,
|
|
3219
|
+
legalName,
|
|
3220
|
+
addressLine1,
|
|
3221
|
+
addressLine2,
|
|
3222
|
+
postalCode,
|
|
3223
|
+
city,
|
|
3224
|
+
country,
|
|
3225
|
+
business,
|
|
3226
|
+
vatId,
|
|
3227
|
+
vatIdValidated,
|
|
3228
|
+
taxNumber,
|
|
3229
|
+
migrated,
|
|
3230
|
+
]
|
|
3231
|
+
properties:
|
|
3232
|
+
id: { type: string }
|
|
3233
|
+
customerNumber: { type: string }
|
|
3234
|
+
legalName: { type: string }
|
|
3235
|
+
addressLine1: { type: string, nullable: true }
|
|
3236
|
+
addressLine2: { type: string, nullable: true }
|
|
3237
|
+
postalCode: { type: string, nullable: true }
|
|
3238
|
+
city: { type: string, nullable: true }
|
|
3239
|
+
country: { type: string, nullable: true }
|
|
3240
|
+
business: { type: boolean, nullable: true }
|
|
3241
|
+
vatId: { type: string, nullable: true }
|
|
3242
|
+
vatIdValidated:
|
|
3243
|
+
type: boolean
|
|
3244
|
+
description: Whether the check that counts for the VAT id found it valid.
|
|
3245
|
+
taxNumber: { type: string, nullable: true }
|
|
3246
|
+
migrated:
|
|
3247
|
+
type: boolean
|
|
3248
|
+
description: Created from the application's own tenant record.
|
|
3249
|
+
readiness:
|
|
3250
|
+
nullable: true
|
|
3251
|
+
description: Null where no tax adapter decides, or the tenant has no subscriber.
|
|
3252
|
+
allOf:
|
|
3253
|
+
- $ref: '#/components/schemas/SubscriberReadiness'
|
|
3254
|
+
|
|
3255
|
+
AdminVatIdCheckOutcome:
|
|
3256
|
+
description: >-
|
|
3257
|
+
A check of a VAT number as the operator is shown it — what the
|
|
3258
|
+
service found, or why the check did not complete.
|
|
3259
|
+
oneOf:
|
|
3260
|
+
- type: object
|
|
3261
|
+
required: [completed, valid, checkedAt, service, counts]
|
|
3262
|
+
properties:
|
|
3263
|
+
completed: { type: boolean, enum: [true] }
|
|
3264
|
+
valid: { type: boolean }
|
|
3265
|
+
checkedAt: { type: string, format: date-time }
|
|
3266
|
+
service: { type: string }
|
|
3267
|
+
counts:
|
|
3268
|
+
type: boolean
|
|
3269
|
+
description: Whether it is the check that counts for the number held now.
|
|
3270
|
+
- type: object
|
|
3271
|
+
required: [completed, reason]
|
|
3272
|
+
properties:
|
|
3273
|
+
completed: { type: boolean, enum: [false] }
|
|
3274
|
+
reason: { type: string }
|
|
3275
|
+
|
|
3276
|
+
AdminSubscriberCorrected:
|
|
3277
|
+
type: object
|
|
3278
|
+
required: [subscriber, vatIdCheck]
|
|
3279
|
+
properties:
|
|
3280
|
+
subscriber: { $ref: '#/components/schemas/AdminTenantSubscriber' }
|
|
3281
|
+
vatIdCheck:
|
|
3282
|
+
nullable: true
|
|
3283
|
+
description: The check a VAT number got, where one was made.
|
|
3284
|
+
allOf:
|
|
3285
|
+
- $ref: '#/components/schemas/AdminVatIdCheckOutcome'
|
|
3286
|
+
|
|
3287
|
+
AdminSubscriberHistoryEntry:
|
|
3288
|
+
description: One correction, change of the tax origin, or check of the VAT number.
|
|
3289
|
+
oneOf:
|
|
3290
|
+
- type: object
|
|
3291
|
+
required: [kind, at, by, previous, corrected, reason]
|
|
3292
|
+
properties:
|
|
3293
|
+
kind: { type: string, enum: [identity-corrected] }
|
|
3294
|
+
at: { type: string, format: date-time }
|
|
3295
|
+
by: { type: string }
|
|
3296
|
+
previous: { type: object, additionalProperties: true }
|
|
3297
|
+
corrected: { type: object, additionalProperties: true }
|
|
3298
|
+
reason: { type: string }
|
|
3299
|
+
- type: object
|
|
3300
|
+
required: [kind, at, by, previous, changed, reason]
|
|
3301
|
+
properties:
|
|
3302
|
+
kind: { type: string, enum: [tax-origin-changed] }
|
|
3303
|
+
at: { type: string, format: date-time }
|
|
3304
|
+
by: { type: string }
|
|
3305
|
+
previous: { type: object, additionalProperties: true }
|
|
3306
|
+
changed: { type: object, additionalProperties: true }
|
|
3307
|
+
reason:
|
|
3308
|
+
type: string
|
|
3309
|
+
nullable: true
|
|
3310
|
+
description: Null for a change of the country with the contact details.
|
|
3311
|
+
- type: object
|
|
3312
|
+
required: [kind, at, vatId, valid, service, counts]
|
|
3313
|
+
properties:
|
|
3314
|
+
kind: { type: string, enum: [vat-id-checked] }
|
|
3315
|
+
at: { type: string, format: date-time }
|
|
3316
|
+
vatId: { type: string }
|
|
3317
|
+
valid: { type: boolean }
|
|
3318
|
+
service: { type: string }
|
|
3319
|
+
counts: { type: boolean }
|
|
3320
|
+
|
|
2435
3321
|
# ────────── User ──────────
|
|
2436
3322
|
AdminUserRow:
|
|
2437
3323
|
type: object
|