includio-cms 0.28.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +39 -13
- package/CHANGELOG.md +19 -0
- package/DOCS.md +1 -1
- package/ROADMAP.md +1 -0
- package/dist/admin/api/handler.js +4 -0
- package/dist/admin/api/integrations.d.ts +13 -0
- package/dist/admin/api/integrations.js +61 -0
- package/dist/admin/api/test-email.d.ts +9 -0
- package/dist/admin/api/test-email.js +39 -0
- package/dist/admin/auth-client.d.ts +2209 -2209
- package/dist/admin/client/index.d.ts +10 -0
- package/dist/admin/client/index.js +12 -0
- package/dist/admin/client/maintenance/maintenance-page.svelte +210 -0
- package/dist/admin/client/shop/coupon-schema.d.ts +1 -1
- package/dist/admin/client/shop/restore-order-cell.svelte +29 -0
- package/dist/admin/client/shop/restore-order-cell.svelte.d.ts +8 -0
- package/dist/admin/client/shop/shop-order-detail-page.svelte +71 -1
- package/dist/admin/client/shop/shop-orders-list-page.svelte +113 -53
- package/dist/admin/components/layout/app-sidebar.svelte +2 -0
- package/dist/admin/components/layout/nav-custom.svelte +26 -0
- package/dist/admin/components/layout/nav-custom.svelte.d.ts +3 -0
- package/dist/admin/components/layout/page-header.svelte +13 -3
- package/dist/admin/components/layout/page-header.svelte.d.ts +13 -3
- package/dist/admin/remote/admin.remote.d.ts +7 -0
- package/dist/admin/remote/admin.remote.js +10 -0
- package/dist/admin/remote/entry.remote.d.ts +4 -4
- package/dist/admin/remote/index.d.ts +1 -0
- package/dist/admin/remote/index.js +1 -0
- package/dist/admin/remote/invite.d.ts +2 -2
- package/dist/admin/remote/shop.remote.d.ts +75 -48
- package/dist/admin/remote/shop.remote.js +41 -10
- package/dist/admin/types.d.ts +15 -0
- package/dist/admin/utils/csv-export.d.ts +45 -0
- package/dist/admin/utils/csv-export.js +61 -0
- package/dist/cli/scaffold/admin.js +1 -1
- package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
- package/dist/components/ui/command/command.svelte.d.ts +1 -1
- package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
- package/dist/components/ui/input/input.svelte.d.ts +1 -1
- package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
- package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
- package/dist/core/cms.d.ts +44 -2
- package/dist/core/cms.js +64 -0
- package/dist/core/index.d.ts +1 -4
- package/dist/core/index.js +4 -4
- package/dist/core/server/index.d.ts +4 -1
- package/dist/core/server/index.js +4 -1
- package/dist/db-postgres/schema/shop/order.d.ts +34 -0
- package/dist/db-postgres/schema/shop/order.js +4 -0
- package/dist/paraglide/messages/_index.d.ts +3 -36
- package/dist/paraglide/messages/_index.js +3 -71
- package/dist/paraglide/messages/hello_world.d.ts +5 -0
- package/dist/paraglide/messages/hello_world.js +33 -0
- package/dist/paraglide/messages/login_hello.d.ts +16 -0
- package/dist/paraglide/messages/login_hello.js +34 -0
- package/dist/paraglide/messages/login_please_login.d.ts +16 -0
- package/dist/paraglide/messages/login_please_login.js +34 -0
- package/dist/shop/adapters/fakturownia/client.d.ts +5 -0
- package/dist/shop/adapters/fakturownia/client.js +20 -0
- package/dist/shop/adapters/fakturownia/index.js +11 -0
- package/dist/shop/adapters/payu/index.js +11 -0
- package/dist/shop/index.d.ts +1 -1
- package/dist/shop/server/coupons.d.ts +10 -0
- package/dist/shop/server/coupons.js +19 -0
- package/dist/shop/server/email.d.ts +7 -3
- package/dist/shop/server/email.js +86 -112
- package/dist/shop/server/emailTemplateRegistry.d.ts +47 -0
- package/dist/shop/server/emailTemplateRegistry.js +288 -0
- package/dist/shop/server/orders.d.ts +60 -1
- package/dist/shop/server/orders.js +145 -16
- package/dist/shop/templates/_partials/footer.en.html +4 -0
- package/dist/shop/templates/_partials/footer.pl.html +4 -0
- package/dist/shop/templates/_partials/header.en.html +4 -0
- package/dist/shop/templates/_partials/header.pl.html +4 -0
- package/dist/shop/templates/_partials/items.en.html +14 -0
- package/dist/shop/templates/_partials/items.pl.html +14 -0
- package/dist/shop/templates/_partials/tracking.en.html +7 -0
- package/dist/shop/templates/_partials/tracking.pl.html +7 -0
- package/dist/shop/templates/awaiting-payment.en.html +6 -0
- package/dist/shop/templates/awaiting-payment.pl.html +6 -0
- package/dist/shop/templates/cancelled.en.html +6 -0
- package/dist/shop/templates/cancelled.pl.html +6 -0
- package/dist/shop/templates/low-stock.en.html +14 -0
- package/dist/shop/templates/low-stock.pl.html +14 -0
- package/dist/shop/templates/order-completed.en.html +6 -0
- package/dist/shop/templates/order-completed.pl.html +6 -0
- package/dist/shop/templates/order-received.en.html +7 -0
- package/dist/shop/templates/order-received.pl.html +7 -0
- package/dist/shop/templates/payment-received.en.html +7 -0
- package/dist/shop/templates/payment-received.pl.html +7 -0
- package/dist/shop/templates/payment-rejected.en.html +6 -0
- package/dist/shop/templates/payment-rejected.pl.html +6 -0
- package/dist/shop/templates/preparing.en.html +7 -0
- package/dist/shop/templates/preparing.pl.html +7 -0
- package/dist/shop/templates/refunded.en.html +6 -0
- package/dist/shop/templates/refunded.pl.html +6 -0
- package/dist/shop/templates/shipped.en.html +7 -0
- package/dist/shop/templates/shipped.pl.html +7 -0
- package/dist/shop/types.d.ts +63 -0
- package/dist/sveltekit/index.d.ts +0 -1
- package/dist/sveltekit/index.js +0 -1
- package/dist/sveltekit/server/index.d.ts +2 -0
- package/dist/sveltekit/server/index.js +4 -0
- package/dist/types/adapters/email.d.ts +13 -0
- package/dist/types/cms.d.ts +30 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/updates/0.34.0/index.d.ts +2 -0
- package/dist/updates/0.34.0/index.js +17 -0
- package/dist/updates/index.js +3 -1
- package/package.json +7 -2
- package/dist/paraglide/messages/en.d.ts +0 -5
- package/dist/paraglide/messages/en.js +0 -14
- package/dist/paraglide/messages/pl.d.ts +0 -5
- package/dist/paraglide/messages/pl.js +0 -14
package/API.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# includio-cms — Public API v0.
|
|
1
|
+
# includio-cms — Public API v0.34.0
|
|
2
2
|
|
|
3
3
|
> Auto-generated by `scripts/generate-api-md.ts`. Do not edit by hand.
|
|
4
4
|
|
|
5
|
-
Entry points: **
|
|
5
|
+
Entry points: **19** · Stable: **487** · Experimental: **4**
|
|
6
6
|
|
|
7
7
|
Tags:
|
|
8
8
|
- `@public` — frozen for v1.0; semver-protected.
|
|
@@ -13,23 +13,25 @@ Tags:
|
|
|
13
13
|
|
|
14
14
|
### `includio-cms`
|
|
15
15
|
|
|
16
|
-
- `
|
|
17
|
-
- `getAuth(): <inferred>` — Returns the underlying `better-auth` instance from the initialized CMS.
|
|
18
|
-
- `getCMS(): CMS` — Returns the singleton CMS instance. Must be called after `includioCMS()`
|
|
19
|
-
- `interface ResolvedMedia` — Resolved media file plus its image styles + blur placeholder. Returned by
|
|
16
|
+
- `interface EmailAdapter` — Contract for email adapters. Used by `better-auth` reset-password flow and form submission
|
|
20
17
|
- `type ResolvedSeo = { [K in keyof SeoFieldData]: K extends 'ogImage' ? string | MediaFile | undefined : string | unde...` — Normalized SEO data — localized values flattened by `language`. A stable
|
|
21
|
-
- `resolveMediaWithStyles(mediaIds: string[], styles?: ImageFieldStyle[]): Promise<Record<string, ResolvedMedia>>` — Resolve media files by IDs and generate image styles. Useful for plugins or
|
|
22
18
|
- `resolveSeo(entry: { seo?: Record<string, unknown> } | Record<string,..., language?: string): ResolvedSeo` — Resolve `entry.seo` into flat fields, flattening localized objects by
|
|
19
|
+
- `interface SendMailOptions`
|
|
23
20
|
|
|
24
21
|
### `includio-cms/core`
|
|
25
22
|
|
|
23
|
+
- `interface EmailAdapter` — Contract for email adapters. Used by `better-auth` reset-password flow and form submission
|
|
24
|
+
- `type ResolvedSeo = { [K in keyof SeoFieldData]: K extends 'ogImage' ? string | MediaFile | undefined : string | unde...` — Normalized SEO data — localized values flattened by `language`. A stable
|
|
25
|
+
- `resolveSeo(entry: { seo?: Record<string, unknown> } | Record<string,..., language?: string): ResolvedSeo` — Resolve `entry.seo` into flat fields, flattening localized objects by
|
|
26
|
+
- `interface SendMailOptions`
|
|
27
|
+
|
|
28
|
+
### `includio-cms/core/server`
|
|
29
|
+
|
|
26
30
|
- `createEntityAPI(cms: CMS, opts?: EntityAPIOptions): <inferred>` — Creates a high-level Entity API (CRUD + publish/archive) bound to a CMS
|
|
27
31
|
- `getAuth(): <inferred>` — Returns the underlying `better-auth` instance from the initialized CMS.
|
|
28
32
|
- `getCMS(): CMS` — Returns the singleton CMS instance. Must be called after `includioCMS()`
|
|
29
33
|
- `interface ResolvedMedia` — Resolved media file plus its image styles + blur placeholder. Returned by
|
|
30
|
-
- `type ResolvedSeo = { [K in keyof SeoFieldData]: K extends 'ogImage' ? string | MediaFile | undefined : string | unde...` — Normalized SEO data — localized values flattened by `language`. A stable
|
|
31
34
|
- `resolveMediaWithStyles(mediaIds: string[], styles?: ImageFieldStyle[]): Promise<Record<string, ResolvedMedia>>` — Resolve media files by IDs and generate image styles. Useful for plugins or
|
|
32
|
-
- `resolveSeo(entry: { seo?: Record<string, unknown> } | Record<string,..., language?: string): ResolvedSeo` — Resolve `entry.seo` into flat fields, flattening localized objects by
|
|
33
35
|
|
|
34
36
|
### `includio-cms/types`
|
|
35
37
|
|
|
@@ -37,6 +39,8 @@ Tags:
|
|
|
37
39
|
- `interface ApiKeyConfig`
|
|
38
40
|
- `interface ArrayField`
|
|
39
41
|
- `interface AuthConfig`
|
|
42
|
+
- `interface AuthRateLimitConfig`
|
|
43
|
+
- `interface AuthRateLimitRule`
|
|
40
44
|
- `interface BaseField`
|
|
41
45
|
- `interface BlocksField`
|
|
42
46
|
- `interface BooleanField`
|
|
@@ -134,19 +138,28 @@ Tags:
|
|
|
134
138
|
|
|
135
139
|
- `const AcceptInvitePage: LegacyComponentType`
|
|
136
140
|
- `const AdminAfterLoginLayout: LegacyComponentType`
|
|
141
|
+
- `interface AdminConfig` — Optional admin UI configuration — extension points for the panel sidebar
|
|
137
142
|
- `const AdminLayout: LegacyComponentType`
|
|
143
|
+
- `interface AdminNavItem` — One additional sidebar entry rendered below built-in nav sections
|
|
138
144
|
- `const Badge: LegacyComponentType`
|
|
145
|
+
- `interface Breadcrumb`
|
|
146
|
+
- `class Breadcrumbs`
|
|
147
|
+
- `buildCsv(opts: { headers: string[]; rows: (string | number | null ...): string` — Build a CSV string from `headers` and `rows`. Values are escaped per
|
|
139
148
|
- `buildCustomFieldsMap(...plugins: PluginConfig[]): Map<string, CustomFieldDefinition>` — Build a Map<fieldType, CustomFieldDefinition> from plugin configs.
|
|
140
149
|
- `buildIconSetMap(...plugins: IconSetPlugin[]): Map<string, IconSetPlugin>` — Build a Map<slug, IconSetPlugin> from icon-set plugin instances.
|
|
141
150
|
- `const Button: LegacyComponentType`
|
|
142
151
|
- `Card`
|
|
143
152
|
- `const CollectionPage: LegacyComponentType`
|
|
153
|
+
- `type ColumnDef = DisplayColumnDef<TData, TValue> | GroupColumnDef<TData, TValue> | AccessorColumnDef<TData, TValue>`
|
|
144
154
|
- `const DashboardPage: LegacyComponentType`
|
|
155
|
+
- `const DataTable: LegacyComponentType`
|
|
145
156
|
- `Dialog`
|
|
157
|
+
- `downloadCsv(opts: { filename: string; csv: string }): void` — Trigger a client-side CSV download. Wraps the given `csv` string in a
|
|
146
158
|
- `const EntryPage: LegacyComponentType`
|
|
147
159
|
- `const FileMiniature: LegacyComponentType`
|
|
148
160
|
- `const FormPage: LegacyComponentType`
|
|
149
161
|
- `const FormSubmissionPage: LegacyComponentType`
|
|
162
|
+
- `getBreadcrumbs`
|
|
150
163
|
- `getContentLanguage`
|
|
151
164
|
- `getCustomFields(): Map<string, CustomFieldDefinition>`
|
|
152
165
|
- `getIconSets(): Map<string, IconSetPlugin>`
|
|
@@ -158,9 +171,12 @@ Tags:
|
|
|
158
171
|
- `const MaintenancePage: LegacyComponentType`
|
|
159
172
|
- `const MediaPage: LegacyComponentType`
|
|
160
173
|
- `const MediaSelector: LegacyComponentType`
|
|
174
|
+
- `const PageHeader: LegacyComponentType`
|
|
175
|
+
- `interface PaginationState`
|
|
161
176
|
- `const ResetPasswordPage: LegacyComponentType`
|
|
162
177
|
- `resolveIconSet(slug?: string): IconSetPlugin | null` — Resolve a single icon set: explicit `slug` (from {@link IconField.set}) takes
|
|
163
178
|
- `const Separator: LegacyComponentType`
|
|
179
|
+
- `setBreadcrumbs`
|
|
164
180
|
- `const ShippingMethodEditPage: LegacyComponentType`
|
|
165
181
|
- `const ShippingMethodNewPage: LegacyComponentType`
|
|
166
182
|
- `const ShippingMethodsListPage: LegacyComponentType`
|
|
@@ -171,6 +187,10 @@ Tags:
|
|
|
171
187
|
- `const ShopOrdersListPage: LegacyComponentType`
|
|
172
188
|
- `const ShopProductsListPage: LegacyComponentType`
|
|
173
189
|
- `const Skeleton: LegacyComponentType`
|
|
190
|
+
- `type SortingState = ColumnSort[]`
|
|
191
|
+
- `const StateDisplay: LegacyComponentType`
|
|
192
|
+
- `const TablePagination: LegacyComponentType`
|
|
193
|
+
- `const TableToolbar: LegacyComponentType`
|
|
174
194
|
- `Tabs`
|
|
175
195
|
- `Tooltip`
|
|
176
196
|
- `useField(form: SuperForm<Record<string, unknown>>, path: FormPathLeaves<Record<string, unknown>>): <inferred>` — Simplified wrapper around sveltekit-superforms' formFieldProxy.
|
|
@@ -195,6 +215,7 @@ Tags:
|
|
|
195
215
|
- `const deleteFormSubmissions: <inferred>`
|
|
196
216
|
- `const deleteMediaFile: <inferred>`
|
|
197
217
|
- `const deleteMediaTag: <inferred>`
|
|
218
|
+
- `const deleteOrderCmd: <inferred>`
|
|
198
219
|
- `const deleteShippingMethodCmd: <inferred>`
|
|
199
220
|
- `const deleteShopDataForEntry: <inferred>`
|
|
200
221
|
- `const exportFormSubmissions: <inferred>`
|
|
@@ -202,6 +223,7 @@ Tags:
|
|
|
202
223
|
- `const findMediaReferences: <inferred>`
|
|
203
224
|
- `const generateAltText: <inferred>`
|
|
204
225
|
- `const generateBalanceLinkForOrder: <inferred>`
|
|
226
|
+
- `const getAdminExtraNavItems: <inferred>`
|
|
205
227
|
- `const getAltOverview: <inferred>`
|
|
206
228
|
- `const getCollection: <inferred>`
|
|
207
229
|
- `const getCollections: <inferred>`
|
|
@@ -250,6 +272,7 @@ Tags:
|
|
|
250
272
|
- `const reorderEntriesCommand: <inferred>`
|
|
251
273
|
- `const reorderShippingMethodsCmd: <inferred>`
|
|
252
274
|
- `const resendOrderEmailCmd: <inferred>`
|
|
275
|
+
- `const restoreOrderCmd: <inferred>`
|
|
253
276
|
- `const searchEntries: <inferred>`
|
|
254
277
|
- `const searchLinkableEntries: <inferred>`
|
|
255
278
|
- `const setFocalPoint: <inferred>`
|
|
@@ -275,10 +298,6 @@ Tags:
|
|
|
275
298
|
- `defineObject(config: Omit<ObjectField, 'type'>): ObjectField` — Defines a reusable object field (nested record). Use inline inside `fields[]`
|
|
276
299
|
- `defineSingle(config: SingleInput): SingleConfig` — Defines a singleton (single-entry content type, e.g. site settings, homepage).
|
|
277
300
|
- `enableHybridEditing(): <inferred>` — Call in a layout/component script to enable data-hybrid-path rendering for all descendant HybridTarget/Image/Video.
|
|
278
|
-
- `extractBlocks(doc: StructuredContentDoc, type?: string): SCNode[]` — Extract block-level nodes, optionally filtered by type.
|
|
279
|
-
- `extractInlineBlocks(doc: StructuredContentDoc, blockType?: string): SCInlineBlockAttrs[]` — Extract inline block nodes, optionally filtered by blockType.
|
|
280
|
-
- `extractMediaRefs(doc: StructuredContentDoc): MediaRef[]` — Extract media references from figure/video/image nodes.
|
|
281
|
-
- `extractText(doc: StructuredContentDoc): string` — Extract all plain text from doc (useful for excerpts, search indexing).
|
|
282
301
|
- `getCustomFields(): Map<string, CustomFieldDefinition>`
|
|
283
302
|
- `getLink(link: string | { url: string | Record<string, string> } |..., language?: string): string` — Resolves a link value to a URL string.
|
|
284
303
|
- `getRemotes(): typeof remotes`
|
|
@@ -304,7 +323,12 @@ Tags:
|
|
|
304
323
|
- `const createConsentLog: <inferred>`
|
|
305
324
|
- `const createFormSubmission: <inferred>`
|
|
306
325
|
- `createRestApiHandler(): <inferred>` — REST API handler factory. Returns `{ GET, POST, PUT, DELETE }`
|
|
326
|
+
- `extractBlocks(doc: StructuredContentDoc, type?: string): SCNode[]` — Extract block-level nodes, optionally filtered by type.
|
|
327
|
+
- `extractInlineBlocks(doc: StructuredContentDoc, blockType?: string): SCInlineBlockAttrs[]` — Extract inline block nodes, optionally filtered by blockType.
|
|
328
|
+
- `extractMediaRefs(doc: StructuredContentDoc): MediaRef[]` — Extract media references from figure/video/image nodes.
|
|
329
|
+
- `extractText(doc: StructuredContentDoc): string` — Extract all plain text from doc (useful for excerpts, search indexing).
|
|
307
330
|
- `generateApiKey(): string` — Generate a cryptographically random API key (32 bytes, base64url-encoded).
|
|
331
|
+
- `getMailer(): EmailAdapter | null` — Returns the configured email adapter from the active CMS singleton, or
|
|
308
332
|
- `getPreviewEntry(event: RequestEvent, options: { language: string }): Promise<Entry | null>` — Resolves the preview entry from a `?preview=<versionId>` query param.
|
|
309
333
|
- `includioCMS(cmsConfig: CMSConfig): Handle[]` — SvelteKit `Handle[]` array that initializes the CMS, generates runtime
|
|
310
334
|
- `parseFormDataForSubmission(formData: FormData, fields: FormField[]): Promise<Record<string, unknown>>` — Parses multipart `FormData` into a typed record of field values, handling
|
|
@@ -314,6 +338,7 @@ Tags:
|
|
|
314
338
|
- `resolveEntry(opts: ResolveEntryOptions): Promise<Entry | null>` — Fetch a single populated Entry.
|
|
315
339
|
- `interface ResolveEntryOptions`
|
|
316
340
|
- `type ResolveStatus = 'published' | 'draft' | 'scheduled'` — Status filter for `resolveEntry`/`resolveEntries`/`countEntries`.
|
|
341
|
+
- `sendMail(options: SendMailOptions): Promise<void>` — Send an email through the configured CMS email adapter. Thin convenience
|
|
317
342
|
|
|
318
343
|
### `includio-cms/db-postgres`
|
|
319
344
|
|
|
@@ -439,6 +464,7 @@ Tags:
|
|
|
439
464
|
- `isValidNip(nip: string): boolean` — Validate a Polish NIP (tax id) — 10 digits with a weighted checksum.
|
|
440
465
|
- `isVariantExpired(variant: VariantLike, config: VariantExpiryConfig | null, now: Date = new Date(Date.now())): boolean` — Check whether a variant has expired under the given config. Fail-open by
|
|
441
466
|
- `manualAdapter(opts: ManualPaymentAdapterOptions = {}): PaymentAdapter` — Manual payment adapter — order goes to awaitingPayment, admin marks as paid later
|
|
467
|
+
- `type Order = typeof shopOrdersTable.$inferSelect` — Public row type for a single shop order — mirrors the Drizzle `shop_orders`
|
|
442
468
|
- `interface OrderRef`
|
|
443
469
|
- `type OrderStatus = | 'new' | 'awaitingPayment' | 'paid' | 'preparing' | 'sent' | 'done' | 'cancelled' | 'paymentReje...`
|
|
444
470
|
- `interface PartialPayment` — Persisted partial-payment summary on `order.partialPayment` when the order
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to includio-cms are documented here.
|
|
4
4
|
Generated from `src/lib/updates/` — do not edit manually.
|
|
5
5
|
|
|
6
|
+
## 0.34.0 — 2026-06-03
|
|
7
|
+
|
|
8
|
+
Soft-delete zamówień (admin-only) — administrator może ukryć zamówienie z listy bez utraty danych. Odwracalne (kosz + przywracanie), bezpieczne księgowo: nie kasuje wiersza, faktur ani historii. Dozwolone tylko dla „bezpiecznych" statusów bez płatności (`new`, `awaitingPayment`, `cancelled`, `paymentRejected`) i zablokowane dla zamówień z wystawioną fakturą. Cała funkcja widoczna wyłącznie dla roli `admin`. Additive only — bez breaking changes.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `shop_orders` dostaje kolumny `deleted_at` (timestamptz, NULL = widoczne) i `deleted_by` (text). Lista zamówień domyślnie ukrywa miękko usunięte; `listOrders`/`countOrders` (`$lib/shop/server/orders.ts`) przyjmują `deleted: "exclude" | "only" | "include"` (domyślnie `exclude`).
|
|
12
|
+
- `softDeleteOrder(orderId, deletedBy)` / `restoreOrder(orderId)` (`$lib/shop/server/orders.ts`, `@public`) — miękkie usuwanie/przywracanie (idempotentne). Soft-delete zwalnia natychmiast aktywną rezerwację stocku (nie czeka na TTL). Guard: `decideOrderDeletion(status, invoice)` + `DELETABLE_ORDER_STATUSES` / `isOrderDeletable(status)` (czyste, testowalne) — rzuca `OrderNotDeletableError` dla niedozwolonego statusu lub faktury `issued`/`sent`.
|
|
13
|
+
- Auto-restore: zmiana statusu miękko usuniętego zamówienia na nieusuwalny (np. spóźniony webhook płatności na ukrytym `awaitingPayment` → `paid`) automatycznie zdejmuje je z kosza — opłacone zamówienia nigdy nie zostają ukryte.
|
|
14
|
+
- Customer-facing `getOrderByNumber` nie zwraca miękko usuniętego zamówienia (nie resolvuje się na storefroncie); admin `getOrderById` celowo ignoruje `deletedAt` (podgląd/przywracanie z kosza).
|
|
15
|
+
- `deleteOrderCmd` / `restoreOrderCmd` (commands) + `listOrdersAdmin({ deleted })` (`includio-cms/admin/remote`) — chronione `requireRole("admin")` (kosz i usuwanie tylko dla admina; normalna lista nadal `requireAuth`).
|
|
16
|
+
- Admin UI: `shop-order-detail-page` zyskuje sekcję „Usuń zamówienie" (tylko admin + status usuwalny) z dialogiem potwierdzenia; `shop-orders-list-page` — przełącznik „Kosz" (tylko admin) z akcją „Przywróć" w wierszu.
|
|
17
|
+
|
|
18
|
+
### Migration
|
|
19
|
+
|
|
20
|
+
```sql
|
|
21
|
+
ALTER TABLE shop_orders ADD COLUMN IF NOT EXISTS deleted_at timestamptz;
|
|
22
|
+
ALTER TABLE shop_orders ADD COLUMN IF NOT EXISTS deleted_by text;
|
|
23
|
+
```
|
|
24
|
+
|
|
6
25
|
## 0.28.0 — 2026-06-01
|
|
7
26
|
|
|
8
27
|
Fakturowanie — integracja sklepu z Fakturownią: automatyczne wystawianie i wysyłka faktury po opłaceniu zamówienia. Nowy generyczny `InvoicingAdapter` (spójny z payment/carrier) + `fakturowniaAdapter()` jako pierwsza implementacja. Faktura wystawiana fire-and-forget gdy zamówienie jest w pełni opłacone (`!balanceOwed` — zaliczki czekają na dopłatę balansu), wysyłana przez Fakturownię (`send_by_email`). Trigger konfigurowalny per-adapter (`issueWhen`: `b2bAndOnRequest` domyślnie / `always`). Checkout zbiera dane B2B (NIP z twardą walidacją sumy kontrolnej, nazwa firmy, adres do faktury, opt-in „chcę fakturę"). Idempotencja przez `shop_invoices` (unikat per zamówienie); ręczny retry w adminie. Additive only — żadnych breaking zmian.
|
package/DOCS.md
CHANGED
package/ROADMAP.md
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
- [x] Faza 6 — envet integration (pilot consumer) — szkolenia variants + deposit flow + balance link end-to-end QA. <!-- files: envet repo src/lib/cms/cms.config.ts, src/routes/api/shop/, src/routes/(website)/{szkolenia,koszyk}/, src/lib/components/{CartIcon,AddToCartModal,CoursePage}.svelte, cli/seed.ts -->
|
|
31
31
|
- [x] Faza 7 — Release artifacts (changelog, ROADMAP cleanup, API.md, build) — 3 post-Faza-5 hotfixy w 0.27.0 (single release). <!-- files: src/lib/updates/0.27.0/index.ts, ROADMAP.md, CHANGELOG.md, API.md, MIGRATION-... -->
|
|
32
32
|
- [x] `[feature]` `[P1]` Slug first-class + SEO v1.0 freeze (0.26.0) — `resolveSeo` public (`includio-cms/core`), `seoFieldDescriptor` SSOT (Zod+TS drift-guard), admin URL un-hardcode (`slugPath.ts` pure resolver, no `seo`-field requirement), `SlugField`/`SeoField`/`SeoFieldData` `@public` v1.0-frozen <!-- files: src/lib/core/fields/slugPath.ts, src/lib/core/fields/seoFieldDescriptor.ts, src/lib/core/fields/resolveSeo.ts, src/lib/types/fields.ts, src/lib/admin/client/collection/collection-entries.svelte, src/lib/updates/0.26.0/ -->
|
|
33
|
+
- [x] `[feature]` `[P2]` Soft-delete zamówień admin-only (0.34.0) — ukrycie zamówienia z listy bez utraty danych (`deleted_at`/`deleted_by`), kosz + przywracanie, guard `decideOrderDeletion` (safe-statuses + faktura), auto-restore przy płatności, zwolnienie rezerwacji stocku, `requireRole('admin')` <!-- files: src/lib/shop/server/orders.ts, src/lib/db-postgres/schema/shop/order.ts, src/lib/admin/remote/shop.remote.ts, src/lib/admin/client/shop/{shop-order-detail-page,shop-orders-list-page,restore-order-cell}.svelte, src/lib/updates/0.34.0/ -->
|
|
33
34
|
|
|
34
35
|
## v1.x — Post-v1.0 deferred
|
|
35
36
|
|
|
@@ -11,6 +11,8 @@ import * as transcodeVideosHandlers from './transcode-videos.js';
|
|
|
11
11
|
import * as uploadLimitHandlers from './upload-limit.js';
|
|
12
12
|
import * as systemInfoHandlers from './system-info.js';
|
|
13
13
|
import * as maintenanceStatusHandlers from './maintenance-status.js';
|
|
14
|
+
import * as integrationsHandlers from './integrations.js';
|
|
15
|
+
import * as testEmailHandlers from './test-email.js';
|
|
14
16
|
import { requireAuth } from '../remote/middleware/auth.js';
|
|
15
17
|
import { getCMS } from '../../core/cms.js';
|
|
16
18
|
import { lookup } from 'mrmime';
|
|
@@ -28,6 +30,8 @@ export function createAdminApiHandler(options) {
|
|
|
28
30
|
'upload-limit': uploadLimitHandlers,
|
|
29
31
|
'system-info': systemInfoHandlers,
|
|
30
32
|
'maintenance-status': maintenanceStatusHandlers,
|
|
33
|
+
integrations: integrationsHandlers,
|
|
34
|
+
'test-email': testEmailHandlers,
|
|
31
35
|
...options?.extraRoutes
|
|
32
36
|
};
|
|
33
37
|
const privateMediaGet = async (event) => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RequestHandler } from '@sveltejs/kit';
|
|
2
|
+
/**
|
|
3
|
+
* Integration diagnostics for the admin maintenance panel.
|
|
4
|
+
*
|
|
5
|
+
* `GET` — report which integrations are configured and whether each supports a
|
|
6
|
+
* connectivity ping. Returns NO secrets (only ids, labels, booleans
|
|
7
|
+
* and the admin notification e-mail used as a UI placeholder).
|
|
8
|
+
* `POST` — run a single adapter's non-invasive `healthCheck()` and return the
|
|
9
|
+
* `{ ok, message }` result. Errors are mapped to `message` text — the
|
|
10
|
+
* underlying secret/token is never serialised to the client.
|
|
11
|
+
*/
|
|
12
|
+
export declare const GET: RequestHandler;
|
|
13
|
+
export declare const POST: RequestHandler;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { json } from '@sveltejs/kit';
|
|
2
|
+
import { requireRole } from '../remote/middleware/auth.js';
|
|
3
|
+
import { getCMS } from '../../core/cms.js';
|
|
4
|
+
/**
|
|
5
|
+
* Integration diagnostics for the admin maintenance panel.
|
|
6
|
+
*
|
|
7
|
+
* `GET` — report which integrations are configured and whether each supports a
|
|
8
|
+
* connectivity ping. Returns NO secrets (only ids, labels, booleans
|
|
9
|
+
* and the admin notification e-mail used as a UI placeholder).
|
|
10
|
+
* `POST` — run a single adapter's non-invasive `healthCheck()` and return the
|
|
11
|
+
* `{ ok, message }` result. Errors are mapped to `message` text — the
|
|
12
|
+
* underlying secret/token is never serialised to the client.
|
|
13
|
+
*/
|
|
14
|
+
export const GET = async () => {
|
|
15
|
+
requireRole('admin');
|
|
16
|
+
const cms = getCMS();
|
|
17
|
+
const shop = cms.shopConfig;
|
|
18
|
+
return json({
|
|
19
|
+
email: {
|
|
20
|
+
configured: !!cms.emailAdapter,
|
|
21
|
+
adminEmail: shop?.adminEmail ?? null
|
|
22
|
+
},
|
|
23
|
+
payment: (shop?.payment ?? []).map((p) => ({
|
|
24
|
+
id: p.id,
|
|
25
|
+
label: p.label,
|
|
26
|
+
canPing: typeof p.healthCheck === 'function'
|
|
27
|
+
})),
|
|
28
|
+
invoicing: shop?.invoicing
|
|
29
|
+
? {
|
|
30
|
+
id: shop.invoicing.id,
|
|
31
|
+
canPing: typeof shop.invoicing.healthCheck === 'function'
|
|
32
|
+
}
|
|
33
|
+
: null
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
export const POST = async ({ request }) => {
|
|
37
|
+
requireRole('admin');
|
|
38
|
+
const body = (await request.json().catch(() => null));
|
|
39
|
+
if (!body || (body.kind !== 'payment' && body.kind !== 'invoicing')) {
|
|
40
|
+
return json({ error: 'Invalid body: expected { kind: "payment" | "invoicing", id? }' }, {
|
|
41
|
+
status: 400
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const shop = getCMS().shopConfig;
|
|
45
|
+
const adapter = body.kind === 'payment'
|
|
46
|
+
? (shop?.payment ?? []).find((p) => p.id === body.id) ?? shop?.payment?.[0]
|
|
47
|
+
: shop?.invoicing ?? null;
|
|
48
|
+
if (!adapter) {
|
|
49
|
+
return json({ error: 'Integration not configured' }, { status: 404 });
|
|
50
|
+
}
|
|
51
|
+
if (typeof adapter.healthCheck !== 'function') {
|
|
52
|
+
return json({ ok: false, message: 'Health-check not supported by this adapter' });
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const result = await adapter.healthCheck();
|
|
56
|
+
return json(result);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
return json({ ok: false, message: e instanceof Error ? e.message : String(e) });
|
|
60
|
+
}
|
|
61
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RequestHandler } from '@sveltejs/kit';
|
|
2
|
+
/**
|
|
3
|
+
* Send a real test e-mail through the configured email adapter, to verify
|
|
4
|
+
* end-to-end SMTP delivery from the admin maintenance panel.
|
|
5
|
+
*
|
|
6
|
+
* Body: `{ to?: string }`. When `to` is empty, falls back to the shop's
|
|
7
|
+
* `adminEmail`. Returns `{ ok }` or `{ ok: false, message }`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const POST: RequestHandler;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { json } from '@sveltejs/kit';
|
|
2
|
+
import { requireRole } from '../remote/middleware/auth.js';
|
|
3
|
+
import { getCMS } from '../../core/cms.js';
|
|
4
|
+
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
5
|
+
/**
|
|
6
|
+
* Send a real test e-mail through the configured email adapter, to verify
|
|
7
|
+
* end-to-end SMTP delivery from the admin maintenance panel.
|
|
8
|
+
*
|
|
9
|
+
* Body: `{ to?: string }`. When `to` is empty, falls back to the shop's
|
|
10
|
+
* `adminEmail`. Returns `{ ok }` or `{ ok: false, message }`.
|
|
11
|
+
*/
|
|
12
|
+
export const POST = async ({ request }) => {
|
|
13
|
+
requireRole('admin');
|
|
14
|
+
const cms = getCMS();
|
|
15
|
+
const mailer = cms.emailAdapter;
|
|
16
|
+
if (!mailer) {
|
|
17
|
+
return json({ ok: false, message: 'Brak skonfigurowanego adaptera e-mail' }, { status: 400 });
|
|
18
|
+
}
|
|
19
|
+
const body = (await request.json().catch(() => null));
|
|
20
|
+
const to = (body?.to?.trim() || cms.shopConfig?.adminEmail || '').trim();
|
|
21
|
+
if (!to) {
|
|
22
|
+
return json({ ok: false, message: 'Brak odbiorcy — podaj adres lub ustaw ADMIN_EMAIL' }, { status: 400 });
|
|
23
|
+
}
|
|
24
|
+
if (!EMAIL_RE.test(to)) {
|
|
25
|
+
return json({ ok: false, message: `Nieprawidłowy adres e-mail: ${to}` }, { status: 400 });
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
await mailer.sendMail({
|
|
29
|
+
to,
|
|
30
|
+
subject: 'AriaCMS — test połączenia e-mail',
|
|
31
|
+
html: '<p>To jest testowa wiadomość wysłana z panelu Konserwacja. Jeśli ją widzisz, integracja e-mail działa poprawnie.</p>',
|
|
32
|
+
text: 'To jest testowa wiadomość wysłana z panelu Konserwacja. Jeśli ją widzisz, integracja e-mail działa poprawnie.'
|
|
33
|
+
});
|
|
34
|
+
return json({ ok: true });
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
return json({ ok: false, message: e instanceof Error ? e.message : String(e) });
|
|
38
|
+
}
|
|
39
|
+
};
|