From 3c06f70191e4f875244e419c2ad0c848f40f2e66 Mon Sep 17 00:00:00 2001 From: Vijay N Date: Mon, 9 Feb 2026 15:30:31 +0530 Subject: [PATCH 01/26] * Added Aviate database migration guide. * Covered fresh install and Flyway adoption scenarios. --- .../aviate/aviate-database-migrations.adoc | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 userguide/aviate/aviate-database-migrations.adoc diff --git a/userguide/aviate/aviate-database-migrations.adoc b/userguide/aviate/aviate-database-migrations.adoc new file mode 100644 index 000000000..cbd12e13f --- /dev/null +++ b/userguide/aviate/aviate-database-migrations.adoc @@ -0,0 +1,248 @@ += Aviate Database Migrations + +This guide explains how Aviate manages database schema migrations and how to validate that migrations have been applied successfully. + +For plugin installation steps, see +link:https://docs.killbill.io/latest/how-to-install-the-aviate-plugin[How to Install the Aviate Plugin]. + +By default, Aviate runs database migrations automatically at startup. This behavior is controlled by the following property: + +---- +com.killbill.billing.plugin.aviate.enableMigrations=true +---- + +When enabled, Flyway initializes the Aviate schema and applies all pending migrations during plugin startup. + +== How Aviate Manages Database Migrations + +Aviate uses Flyway to version and apply database schema changes. + +At startup, Flyway: + +* Creates the `aviate_schema_history` table if it does not already exist +* Applies migrations in version order +* Tracks applied migrations to prevent duplicate or partial execution + + +== Migration Scenarios + +=== Scenario 1: Fresh Install (No Existing Aviate Schema) + +This scenario applies to brand-new installations where Aviate has never been started against the target database. + +==== Symptoms + +* No `aviate_*` tables exist. +* The `aviate_schema_history` table is not present. + +==== Expected Action + +Start the Aviate plugin. Flyway will automatically: + +* Create the schema history table +* Apply all migrations +* Initialize the Aviate schema + +No manual intervention is required. + +==== What to Verify + +After the plugin starts successfully: + + 1. Confirm that the schema history table exists: + + ---- + SHOW TABLES LIKE 'aviate_schema_history'; + ---- + + + 2. Verify that migrations were applied: + + ---- + SELECT version, description, success + FROM aviate_schema_history + ORDER BY installed_rank DESC; + ---- + + All rows should show: + + ---- + success = 1 + ---- + + 3. Confirm that the expected `aviate_*` tables are present. + +==== Expected Logs + +Look for log entries similar to the following: + +---- +Migrations are enabled. Starting migration process... +Schema history table `killbill`.`aviate_schema_history` does not exist yet +Successfully validated 16 migrations (execution time 00:00.026s) +Successfully applied 16 migrations to schema `killbill`, now at version v1.16.0 (execution time 00:07.871s) +Migration process completed successfully +---- + +=== Scenario 2 — Existing Aviate Schema but No `aviate_schema_history` (Adopting into Flyway) + +This scenario occurs when Aviate tables already exist in the database, but Flyway has never been used to track migrations. + +This is common when the schema was created manually. + +==== Symptoms + +* `aviate_*` tables exist. +* The `aviate_schema_history` table is missing. + +==== Failure Mode + +When the plugin starts, Flyway assumes the database is empty and attempts to run the initial migrations. + +Since the tables already exist, the migration fails with errors similar to: + +---- +Schema history table `killbill`.`aviate_schema_history` does not exist yet +Creating Schema History table `killbill`.`aviate_schema_history` with baseline ... +Migrating schema `killbill` to version "1.1.0 - Initial version" +Error: 1050-42S01: Table 'aviate_hosts' already exists +---- + +Subsequent restarts continue to fail because Flyway retries the same migration. + +==== Root Cause + +Flyway has no record of previously applied migrations and cannot determine the current schema version. + +The database must be baselined so Flyway can begin tracking migrations from the correct version. + +Selecting the wrong baseline version can cause Flyway to either: + +* Re-run migrations against existing objects, or +* Skip required migrations, leading to runtime failures. + +Always validate the baseline version before proceeding. + +==== Resolution — Align Flyway with the Existing Schema (Baselining) + +When migrations are enabled (`com.killbill.billing.plugin.aviate.enableMigrations=true`), Flyway automatically creates the `aviate_schema_history` table and attempts to apply migrations. +If the schema already exists, Flyway must be aligned with the current database state by setting the correct baseline. + +===== Step 1 — Identify the Aviate Plugin Version That Created the Schema + +The KPM bundles directory contains the migration files packaged with each installed Aviate plugin version. + +The path is controlled by: + +---- +org.killbill.billing.plugin.kpm.bundlesPath +---- + +Default path: + +---- +/var/lib/killbill/bundles +---- + +Example: + +---- +/var/lib/killbill/bundles/plugins/java/aviate-plugin/ +├── 1.0.18 +├── 1.0.19 +├── 1.0.27 +└── SET_DEFAULT +---- + +Each version contains a plugin JAR: `aviate-plugin-.jar` + +Locate the Aviate plugin version whose migrations most closely match the existing database schema. + +• If the schema origin is known, use that plugin version. +• Otherwise, start with the latest installed version and compare its migrations against the database. + +Extract the plugin JAR: +---- +unzip aviate-plugin-1.0.19.jar -d aviate-plugin-1.0.19 +---- + +Then inspect: +---- +db/migration/mysql + +or + +db/migration/postgresql +---- + +Migration files follow the following format: + +---- +aviateV1.1.0__Initial_version.sql +aviateV1.2.0__catalog_usage.sql +aviateV1.3.0__catalog_meter.sql +---- + +The last migration file represents the schema version created by that plugin release. + +Example: + +---- +aviateV1.7.0__ledger.sql +---- + +✅ Baseline version = **1.7.0** + +===== Step 2 — Check for Failed Migrations +---- +SELECT * FROM aviate_schema_history; +---- +If a row shows: +---- +success = 0 +---- + +remove **only that failed entry**: + +---- +DELETE FROM aviate_schema_history +WHERE success = 0; +---- + +===== Step 3 — Insert the Correct Baseline + +Insert a row matching the schema already present in the database. + +Example: + +---- +INSERT INTO aviate_schema_history +(installed_rank, version, description, type, script, installed_by, execution_time, success) +VALUES +(2, '1.7.0', '<< Flyway Baseline >>', 'BASELINE', 'aviateV1.7.0__ledger.sql', CURRENT_USER(), 0, 1); +---- + +===== Step 4 — Restart the Aviate Plugin + +On startup: + +* Flyway detects the baseline. + +* Older migrations are skipped. + +* Only newer migrations are applied. + +==== Verification + +---- +SELECT installed_rank, version, success +FROM aviate_schema_history; +---- + +Confirm: + +* No rows with success = 0 + +* Baseline version is present + +* New migrations complete successfully \ No newline at end of file From 14c4fde1a37238a99d694b37280ea3d32c028f80 Mon Sep 17 00:00:00 2001 From: Vijay N Date: Wed, 11 Feb 2026 19:56:30 +0530 Subject: [PATCH 02/26] Documented scenarios like Aviate plugin upgrade, fix failed migration, schema drift, baseline too low or too high, and concurrent startup. --- .../aviate/aviate-database-migrations.adoc | 532 +++++++++++++++++- 1 file changed, 516 insertions(+), 16 deletions(-) diff --git a/userguide/aviate/aviate-database-migrations.adoc b/userguide/aviate/aviate-database-migrations.adoc index cbd12e13f..9606813bf 100644 --- a/userguide/aviate/aviate-database-migrations.adoc +++ b/userguide/aviate/aviate-database-migrations.adoc @@ -128,17 +128,25 @@ Always validate the baseline version before proceeding. When migrations are enabled (`com.killbill.billing.plugin.aviate.enableMigrations=true`), Flyway automatically creates the `aviate_schema_history` table and attempts to apply migrations. If the schema already exists, Flyway must be aligned with the current database state by setting the correct baseline. -===== Step 1 — Identify the Aviate Plugin Version That Created the Schema +===== Step 1 — Retrieve the Migration Files -The KPM bundles directory contains the migration files packaged with each installed Aviate plugin version. +Migration scripts are packaged inside each Aviate plugin JAR. -The path is controlled by: +If you already know which Aviate plugin version created the schema, download that exact version: + +---- +curl -O "https://dl.cloudsmith.io//killbill/aviate/maven/com/kill-bill/billing/plugin/java/aviate-plugin//aviate-plugin-.jar" +---- + +Otherwise, use the latest plugin version available on the Kill Bill node. + +The plugin directory is controlled by: ---- org.killbill.billing.plugin.kpm.bundlesPath ---- -Default path: +Default location: ---- /var/lib/killbill/bundles @@ -148,22 +156,18 @@ Example: ---- /var/lib/killbill/bundles/plugins/java/aviate-plugin/ -├── 1.0.18 -├── 1.0.19 -├── 1.0.27 +├── 1.0.28 +├── 1.0.29 └── SET_DEFAULT ---- Each version contains a plugin JAR: `aviate-plugin-.jar` -Locate the Aviate plugin version whose migrations most closely match the existing database schema. - -• If the schema origin is known, use that plugin version. -• Otherwise, start with the latest installed version and compare its migrations against the database. +Select the version whose migrations most closely match the existing database schema. Extract the plugin JAR: ---- -unzip aviate-plugin-1.0.19.jar -d aviate-plugin-1.0.19 +unzip aviate-plugin-1.0.29.jar -d aviate-plugin-1.0.29 ---- Then inspect: @@ -188,10 +192,10 @@ The last migration file represents the schema version created by that plugin rel Example: ---- -aviateV1.7.0__ledger.sql +aviateV1.8.0__notifications.sql ---- -✅ Baseline version = **1.7.0** +✅ Baseline version = **1.8.0** ===== Step 2 — Check for Failed Migrations ---- @@ -219,7 +223,7 @@ Example: INSERT INTO aviate_schema_history (installed_rank, version, description, type, script, installed_by, execution_time, success) VALUES -(2, '1.7.0', '<< Flyway Baseline >>', 'BASELINE', 'aviateV1.7.0__ledger.sql', CURRENT_USER(), 0, 1); +(2, '1.8.0', '<< Flyway Baseline >>', 'BASELINE', 'aviateV1.8.0__notifications.sql', CURRENT_USER(), 0, 1); ---- ===== Step 4 — Restart the Aviate Plugin @@ -245,4 +249,500 @@ Confirm: * Baseline version is present -* New migrations complete successfully \ No newline at end of file +* New migrations complete successfully + +=== Scenario 3 — Upgrade Aviate Plugin When Flyway Is Already Managing the Schema + +==== Symptoms + +* The `aviate_schema_history` table exists. +* Plugin starts without migration failures. +* No rows in `aviate_schema_history` show success = 0. + +==== Action + +Upgrade the Aviate plugin using the standard uninstall → install workflow. + +Uninstalling the plugin **does not remove** any `aviate_*` tables or the schema history table. + + +==== Uninstall the Existing Plugin + +Send a POST request to `/1.0/kb/nodesInfo`, here is a sample request to uninstall a plugin + +---- +curl -v \ + -u admin: \ + -H "Content-Type: application/json" \ + -H 'X-Killbill-CreatedBy: admin' \ + -X POST \ + --data-binary '{ + "nodeCommandProperties": [ + { + "key": "pluginKey", + "value": "aviate" + }, + { + "key": "pluginVersion", + "value": "" + } + ], + "nodeCommandType": "UNINSTALL_PLUGIN", + "isSystemCommandType": true + }' \ + "http://127.0.0.1:8080/1.0/kb/nodesInfo" +---- + +==== Expected Logs + +---- +Starting uninstallation of plugin: pluginKey=aviate, version=1.0.29 +Deleted plugin directory: /var/lib/killbill/bundles/plugins/java/aviate-plugin/1.0.29 +Unregistering service='aviate-plugin' +Successfully uninstalled plugin: pluginKey=aviate, version=1.0.29 +---- + +==== Install the Upgraded Plugin + +Sample request to install an Aviate plugin +---- +curl -v \ + -u admin:password \ + -H "Content-Type: application/json" \ + -H 'X-Killbill-CreatedBy: admin' \ + -X POST \ + --data-binary '{ + "nodeCommandProperties": [ + { + "key": "pluginKey", + "value": "aviate" + }, + { + "key": "pluginVersion", + "value": "" + }, + { + "key": "pluginArtifactId", + "value": "aviate-plugin" + }, + { + "key": "pluginGroupId", + "value": "com.kill-bill.billing.plugin.java" + }, + { + "key": "pluginType", + "value": "java" + }, + { + "key": "pluginUri", + "value": "https://dl.cloudsmith.io//killbill/aviate/maven/com/kill-bill/billing/plugin/java/aviate-plugin//aviate-plugin-.jar" + } + ], + "nodeCommandType": "INSTALL_PLUGIN", + "isSystemCommandType": "true" + }' \ + "http://127.0.0.1:8080/1.0/kb/nodesInfo" +---- + +==== What to Verify + +After installation: + +* The plugin starts successfully. +* Flyway appends new rows to `aviate_schema_history`. +* No rows in `aviate_schema_history` show success = 0. +* No migration errors appear in the logs. + + +=== Scenario 4 — Failed Migration Recorded in aviate_schema_history (success = 0) + +==== Symptoms + +* Plugin startup fails with errors such as: + + "Detected failed migration to version 1.7.0 (ledger)." + "FlywayValidateException: Validate failed: Migrations have failed validation" + +* The latest row in `aviate_schema_history` shows: + +---- +success = 0 +---- + +==== Root Cause + +A Flyway migration started but did not complete successfully. + +Although the Aviate plugin automatically attempts a Flyway repair, the repair only fixes the schema history table -- it does not undo partially applied database changes. + +Manual cleanup is often required before the migration can succeed. + +==== Action — Correct Remediation Flow + +===== Step 1 — Identify the Failed Migration + +---- +SELECT * +FROM aviate_schema_history +ORDER BY installed_rank DESC; +---- + +Note the migration version where `success = 0`. + +===== Step 2 — Inspect Partial Changes + +Review the migration script referenced in the error logs. + +Migration scripts are packaged inside the Aviate plugin JAR. + +Locate the plugin directory (see the value of `org.killbill.billing.plugin.kpm.bundlesPath` property), by default its at the following location: + +---- +/var/lib/killbill/bundles/plugins/java/aviate-plugin// +---- + +Extract the JAR: + +---- +unzip aviate-plugin-.jar -d aviate-plugin +---- + +Then navigate to: + +---- +db/migration/mysql + +or + +db/migration/postgresql +---- + +Open the migration file mentioned in the logs to understand what schema changes were attempted. + +Example: + +---- +Migration aviateV1.7.0__ledger.sql failed +Table 'aviate_wallets' already exists +---- + +Determine whether the migration: + +* Created some tables or columns +* Added indexes +* Modified constraints + +===== Step 3 — Revert or Align the Database + +Bring the database to the expected pre-migration state. + +Typical fixes include: + +* Dropping partially created tables +* Removing incomplete indexes +* Reverting schema alterations + +Example: + +---- +DROP TABLE aviate_wallets; +---- + +===== Step 4 — Restart the Aviate Plugin + +On restart: + +* Aviate triggers Flyway. +* Flyway validates the schema. +* The repaired migration is executed again. + +===== What to Verify + +After startup: + +* No migration errors appear in logs. +* The previously failed migration now shows: + +---- +success = 1 +---- + +* New migrations continue normally. + +===== Expected Logs: +---- +FlywayValidateException: Validate failed: Migrations have failed validation +Successfully repaired schema history table `killbill`.`aviate_schema_history` (execution time 00:00.017s). +Flyway repair completed. Retrying migration... +Successfully applied 2 migrations to schema `killbill`, now at version v1.8.0 (execution time 00:00.536s) +Migration completed successfully after repair +Migration process completed successfully +---- + +=== Scenario 5 — Schema Drift or Checksum Mismatch + +==== Symptoms + +* Aviate plugin fails during startup. +* Flyway validation reports checksum mismatch or indicates that a migration was applied but differs from the current script. +* Flyway or database errors reference missing columns, tables, or altered objects, for example: + +---- +Migration of schema `killbill` to version "1.10.0 - invoice sequence rename columns" failed! Please restore backups and roll back database and code! + +Error: 1054-42S22: Unknown column 'kb_account_id' in 'aviate_invoice_sequences' + +SQL State : 42S22 +Error Code : 1054 +Message : (conn=10) Unknown column 'kb_account_id' in 'aviate_invoice_sequences' +Location : db/migration/mysql/aviateV1.10.0__invoice_sequence_rename_columns.sql (/db/migration/mysql/aviateV1.10.0__invoice_sequence_rename_columns.sql) +Line : 7 +---- + +==== Root Cause + +The database schema does not match the migration history recorded by Flyway. + +This typically occurs when: + +* Migration scripts were modified after being applied. +* A different plugin artifact was deployed against an existing database. +* Manual schema changes were made outside Flyway. +* The database was restored from a snapshot that does not align with the plugin version. + +Flyway validates migration checksums but cannot detect all forms of schema drift, which can lead to runtime failures even when validation succeeds. + +==== Resolution — Realign Schema with Migration History + +===== Step 1 — Identify the Expected Migration + +Review the error logs to determine which column, table, or object is missing or inconsistent. + +Example: + +---- +Unknown column 'kb_account_id' +---- + +This indicates that the migration responsible for adding this column was never applied or was reverted. + +===== Step 2 — Locate the Migration Script + +Migration scripts are packaged inside the Aviate plugin JAR. + +Locate the plugin directory: + +---- +/var/lib/killbill/bundles/plugins/java/aviate-plugin// +---- + +Extract the JAR: + +---- +unzip aviate-plugin-.jar -d aviate-plugin +---- + +Then navigate to: + +---- +db/migration/mysql + +or + +db/migration/postgresql +---- + +Locate the migration file referenced in the error logs and review it to determine which column, table, or object is missing from the schema. + +===== Step 3 — Verify Schema vs Migration History + +Confirm whether the change exists in the database: + +---- +SHOW COLUMNS FROM aviate_notifications; +---- + +Possible outcomes: + +**Column missing** + +→ The migration was never applied, even though Flyway believes it was. + +**Column exists but differs** + +→ The schema was manually altered. + +===== Step 4 — Choose the Correct Remediation Path + +**If the migration should have run but did not:** + +Apply the schema change manually using the migration script, then restart the plugin. + +**If migration scripts were modified after deployment:** + +Restore the original migration files that match the recorded checksums. + +**If manual database changes caused the drift:** + +Revert the schema to match the migration. + + +=== Scenario 6 — Incorrect Baseline Version (Too Low or Too High) + +==== Symptoms + +**Baseline Too Low** + +Flyway attempts to re-run migrations that were already applied, resulting in errors such as: + +---- +FlywayMigrateException: Migration aviateV1.3.0__catalog_meter.sql failed + +SQL State : 42S01 +Error Code : 1050 +Message : Table 'aviate_billing_meters' already exists +---- + +**Baseline Too High** + +Flyway skips required migrations because it assumes the schema is newer than it actually is. +The plugin may start, but runtime failures occur due to missing objects. + +Example: + +---- +Current version of schema `killbill`: 1.15.0 +Migrating schema `killbill` to version "1.16.0" + +Migration process completed successfully + +org.jooq.exception.DataAccessException: SQL [insert into aviate_health_reports (creating_owner, report_data_gz, created_date, updated_date) values (?, ?, ?, ?) on duplicate key update aviate_health_reports.report_data_gz = ?, aviate_health_reports.updated_date = ?]; (conn=45) Table 'killbill.aviate_health_reports' doesn't exist + +Caused by: java.sql.SQLSyntaxErrorException: (conn=45) Table 'killbill.aviate_health_reports' doesn't exist +---- + +==== Root Cause + +The baseline version recorded in `aviate_schema_history` does not accurately represent the actual database schema. + +* **Too low** → Flyway replays migrations. +* **Too high** → Flyway skips migrations that were never applied. + +==== Recommended Resolution (Safest Approach) + +Restore the database from a known good backup and repeat the baselining process using the correct migration version. + +This is the lowest-risk recovery strategy for production systems. + +==== Surgical Fix (Advanced — Use With Caution) + +Only perform this procedure if: + +* A database backup exists. +* The schema state has been carefully verified. +* You fully understand which migrations have actually been applied. + +===== Step 1 — Stop Kill Bill + +Prevent additional migrations or schema changes while correcting the baseline. + +===== Step 2 — Identify the Correct Migration Version + +Inspect the plugin migration scripts: + +---- +db/migration/mysql +or +db/migration/postgresql +---- + +Compare them with the database schema to determine the latest migration already reflected in the database. + +Indicators: + +* "already exists" → baseline is too low +* Missing table/column → baseline is too high + +===== Step 3 — Correct the Baseline Entry + +Check the current history: + +---- +SELECT * FROM aviate_schema_history ORDER BY installed_rank; +---- + +Update the baseline by removing the incorrect entry: + +---- +DELETE FROM aviate_schema_history +WHERE version = ''; +---- + +Insert the correct baseline: + +---- +INSERT INTO aviate_schema_history +(installed_rank, version, description, type, script, installed_by, execution_time, success) +VALUES +(, '', '<< Flyway Baseline >>', 'BASELINE', + 'aviateV__.sql', CURRENT_USER(), 0, 1); +---- + +===== Step 4 — Restart the Aviate Plugin + +On startup: + +* Flyway validates the schema. +* Only missing migrations are applied. +* Duplicate migrations are skipped. + + +=== Scenario 7 — Concurrent Startup (Multiple Aviate Nodes Running Migrations) + +==== Symptoms + +* Aviate plugin startup fails intermittently. +* Flyway reports lock wait timeouts, deadlocks, or messages such as: ++ +---- +Schema history table is being modified +---- +* One node starts successfully while others fail during migration. + +==== Root Cause + +Multiple Aviate nodes attempt to execute Flyway migrations at the same time. +Although Flyway uses a schema history lock, certain database setups (for example, proxies or misconfigured clusters) can interfere with proper locking. + +==== Resolution + +1. **Run migrations from a single node** ++ +Ensure only one Aviate instance performs migrations during deployment. ++ +Common approaches include: ++ +* Temporarily scale the deployment to one node. +* Disable the Aviate plugin on other nodes until migration completes. +* Use a dedicated migration job before bringing all nodes online. + +2. **Verify database locking behavior** ++ +Confirm that Flyway can acquire an exclusive lock on the Aviate schema history table. ++ +Check for environments that may weaken locking, such as: ++ +* Read replicas being used unintentionally for migrations. +* Database proxies or load balancers routing connections to different writers. +* Cluster configurations without proper write coordination. + +3. **Restart remaining nodes** ++ +After migrations complete successfully, start the other Aviate nodes. + +==== Prevention + +* Execute migrations as part of a controlled deployment step before scaling services. +* Avoid parallel application startups when schema changes are included. +* Validate database topology so migrations always run against the primary writable instance. + From 834229141cfeec2a936c4e51d8143c33c5d9fddd Mon Sep 17 00:00:00 2001 From: Pierre-Alexandre Meyer Date: Thu, 12 Feb 2026 21:07:31 +0000 Subject: [PATCH 03/26] CSS tweaks Signed-off-by: Pierre-Alexandre Meyer --- stylesheets/kb.css | 325 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 287 insertions(+), 38 deletions(-) diff --git a/stylesheets/kb.css b/stylesheets/kb.css index ca725027b..c82ce6613 100644 --- a/stylesheets/kb.css +++ b/stylesheets/kb.css @@ -35,7 +35,7 @@ dd { } :root { - --color: #5C6287; + --color: #474B6B; --primary-color: #155EEF; --link-color: #2970ff; --heading-color: #293056; @@ -62,12 +62,46 @@ dd { --snippet-header-bg: #475467; --snippet-header-color: #EFF4FF; --snippet-body-bg: #344054; - --snippet-body-color: #D0D5DD; + --snippet-body-color: #E0E4EB; --snippet-body-border-color: #475467; + + /* Spacing scale (4px base) */ + --space-1: 4px; + --space-2: 8px; + --space-3: 16px; + --space-4: 24px; + --space-5: 32px; + --space-6: 48px; + + /* Docs typography */ + --docs-content-max-width: 820px; + --docs-line-height: 1.65; + --font-size-sm: 13px; + --font-size-xs: 12px; + --font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace; + + /* Inline code */ + --inline-code-bg: #F3F4F6; + --inline-code-border: #E5E7EB; + + /* Admonition: tip */ + --admon-tip-bg: #F0FDF4; + --admon-tip-border: #BBF7D0; + --admon-tip-accent: #16A34A; + /* Admonition: warning */ + --admon-warning-bg: #FFFBEB; + --admon-warning-border: #FDE68A; + --admon-warning-accent: #D97706; + /* Admonition: important / caution */ + --admon-important-bg: #FEF2F2; + --admon-important-border: #FECACA; + --admon-important-accent: #DC2626; + /* Admonition: note (existing colors) */ + --admon-note-accent: #2970FF; } [data-theme="dark"] { - --color: #D0D5DD; + --color: #D8DCE4; --heading-color: #EAECF0; --content-bg: #F2F4F7; --background-color: #101828; @@ -86,6 +120,25 @@ dd { --sidebar-control-bg: #1D2939; --sidebar-control-color: #fff; + + /* Inline code (dark) */ + --inline-code-bg: #1D2939; + --inline-code-border: #344054; + + /* Admonition: tip (dark) */ + --admon-tip-bg: #052E16; + --admon-tip-border: #14532D; + --admon-tip-accent: #22C55E; + /* Admonition: warning (dark) */ + --admon-warning-bg: #422006; + --admon-warning-border: #78350F; + --admon-warning-accent: #FBBF24; + /* Admonition: important / caution (dark) */ + --admon-important-bg: #450A0A; + --admon-important-border: #7F1D1D; + --admon-important-accent: #F87171; + /* Admonition: note (dark) */ + --admon-note-accent: #528BFF; } html { @@ -98,7 +151,7 @@ body { text-rendering: optimizeSpeed; font-family: 'Inter', sans-serif; font-size: 15px; - line-height: 150%; + line-height: var(--docs-line-height); color: var(--color); background-color: var(--background-color) !important; max-width: 100%; @@ -133,9 +186,21 @@ select { a { color: var(--link-color); word-break: break-word; + transition: color 0.15s; } a:not(.btn):hover { color: var(--link-color)!important; + text-decoration: underline; +} +a:focus-visible { + outline: 2px solid var(--link-color); + outline-offset: 2px; + border-radius: 2px; +} +button:focus-visible, +input:focus-visible { + outline: 2px solid var(--link-color); + outline-offset: 2px; } h1, h3, @@ -149,20 +214,24 @@ h4 { } h1 { font-size: 40px; - line-height: 120%; - letter-spacing: -0.015em; + line-height: 1.15; + letter-spacing: -0.02em; color: var(--heading-color); } h2 { - font-size: 36px; + font-size: 30px; font-weight: 500; + line-height: 1.25; + letter-spacing: -0.015em; } h3 { font-size: 24px; + line-height: 1.3; } h4 { font-size: 18px; font-weight: 500; + line-height: 1.4; } strong { @@ -275,9 +344,12 @@ strong { pointer-events: none; } .content-wrapper { - padding: 24px; + padding: var(--space-4); width: 100%; } +.content-wrapper #content { + max-width: var(--docs-content-max-width); +} @media (min-width: 1020px) { .content-wrapper { padding: 0px 40px 40px 40px; @@ -298,8 +370,9 @@ strong { position: relative; display: flex; align-items: center; - padding: 56px 0px 12px 0px; + padding: 56px 0px var(--space-5) 0px; border-radius: 8px; + max-width: var(--docs-content-max-width); } .content-wrapper .banner .bg-image { position: absolute; @@ -316,7 +389,7 @@ strong { } .main p { - margin-bottom: 12px; + margin-bottom: var(--space-3); } .main .sidebar { @@ -421,8 +494,10 @@ strong { } .main .sidebar-nav a.nav-link { - padding: 8px 12px 6px 12px; + padding: 8px 12px; margin-left: 8px; + font-size: 13.5px; + transition: background-color 0.15s, color 0.15s; } .main .sidebar-nav a.nav-link:hover { color: var(--link-color); @@ -554,6 +629,17 @@ pre.pygments .tok-o { color: #84ADFF; } +/* Inline code styling */ +.main #content code:not(pre code) { + background-color: var(--inline-code-bg); + border: 1px solid var(--inline-code-border); + border-radius: 4px; + padding: 1px 5px; + font-size: 0.88em; + font-family: var(--font-mono); + color: var(--color); + word-break: break-word; +} .main p code { color: inherit; font-size: inherit; @@ -563,7 +649,8 @@ pre.pygments .tok-o { border-radius: 12px; border: 1px solid var(--color-gray-200); background: linear-gradient(180deg, var(--color-gray-50), transparent); - margin-bottom: 15px; + margin-bottom: var(--space-4); + overflow-x: auto; } .main .table-wrap .tableblock tbody { border-radius: 9px; @@ -586,18 +673,26 @@ pre.pygments .tok-o { } .main table, .main table td,.main table th { - padding: 12px; + padding: 14px 16px; font-weight: 500; font-size: 14px; } +.main table th { + background-color: var(--color-gray-50); + font-weight: 600; + color: var(--heading-color); + font-size: 13px; + text-transform: none; +} .main table td:not(:first-child),.main table th:not(:first-child) { border-left: 1px solid var(--color-gray-200); font-size: 14px; - line-height: 21px; + line-height: 1.5; } .main table td { font-weight: 400 !important; color: var(--color); + vertical-align: top; } .main table, .main .admonitionblock table tr, .main table tr:not(:first-child):is(:last-child) { border-bottom: none !important; @@ -754,17 +849,19 @@ ul.nav.navbar-nav { .main .right-side-menu > .navbar-nav:before { content: "In this document"; display: block; - margin-bottom: 28px; - font-weight: 600; - font-size: 15px; + margin-bottom: var(--space-4); + font-weight: 500; + font-size: var(--font-size-xs); line-height: 18px; + letter-spacing: 0.04em; + text-transform: uppercase; color: var(--heading-color); } .main .right-side-menu > ul > li > a { - font-size: 14px; - font-weight: 300; - margin-bottom: 8px; + font-size: var(--font-size-sm); + font-weight: 400; + margin-bottom: 10px; padding: 0; } @@ -772,9 +869,10 @@ ul.nav.navbar-nav { padding-left: 10px !important; border-left: 2px solid transparent; color: var(--color) !important; - line-height: 18px; - font-size: 12px; + line-height: 20px; + font-size: var(--font-size-sm); font-weight: 400; + transition: color 0.15s, border-color 0.15s; } .main .right-side-menu ul ul li .nav-link { @@ -868,11 +966,11 @@ ul.nav.navbar-nav { color: white !important; } .main .listingblock, .literalblock > .content pre { - padding: 8px 14px; + padding: 14px 18px; background: var(--snippet-body-bg) !important; border: 1px solid var(--snippet-body-border-color); border-radius: 12px; - margin-bottom: 24px; + margin-bottom: var(--space-4); font-size: 14px; font-weight: 400; color: white !important; @@ -881,6 +979,7 @@ pre.pygments { background: var(--snippet-body-bg) !important; margin-bottom: 0; color-scheme: dark; + overflow-x: auto; } pre.pygments .table-wrap, pre.pygments tbody { background: transparent !important; @@ -905,12 +1004,13 @@ pre.pygments .tok-ss { list-style: none; color: var(--link-color); margin-left: 20px; - margin-bottom: 16px; + margin-bottom: var(--space-3); } .main ol > li { position: relative; counter-increment: my-awesome-counter; font-weight: 600; + margin-bottom: var(--space-2); } .main ol.arabic > li::before { @@ -943,11 +1043,15 @@ pre.pygments .tok-ss { color: var(--color); list-style: disc; margin-left: 20px; + margin-bottom: var(--space-3); +} +.main .content-wrapper ul > li { + margin-bottom: var(--space-1); } - .main .content-wrapper ul > li ul { margin-left: 0; list-style-type: none; + margin-top: var(--space-1); } /* @media (max-width: 1200px) { @@ -992,14 +1096,29 @@ pre.pygments .tok-ss { color: #6B7280; } -.main h2, .main h3 { - margin-bottom: 16px; - padding-top: 24px; +.main h2 { + margin-bottom: var(--space-3); + margin-top: var(--space-6); + padding-top: 0; +} +.main h3 { + margin-bottom: var(--space-3); + margin-top: var(--space-5); + padding-top: 0; } - .main h4 { - margin-bottom: 16px; - padding-top: 16px; + margin-bottom: var(--space-3); + margin-top: var(--space-4); + padding-top: 0; +} +/* Remove top margin from first heading after banner */ +.main #content > .sect1:first-child > h2 { + margin-top: 0; +} +/* Section separators between major sections */ +.main #content > .sect1 + .sect1 { + border-top: 1px solid var(--color-gray-200); + padding-top: var(--space-6); } .content-wrapper h2 a, .content-wrapper h3 a, .content-wrapper h4 a { @@ -1051,8 +1170,9 @@ pre.pygments .tok-ss { } .banner h1 { - font-size: 48px; + font-size: clamp(32px, 5vw, 48px); font-weight: 500; + line-height: 1.1; } .banner .absolute-figure { @@ -1144,7 +1264,7 @@ pre code { pre.pygments span { font-weight: 400 !important; - font-size: 12px; + font-size: 13px; line-height: 21px; color: var(--snippet-body-color); } @@ -1256,7 +1376,7 @@ pre.pygments [data-lang="bash"] .tok-s1 { align-items: center; justify-content: space-between; height: 36px; - margin: -8px -14px 8px; + margin: -14px -18px 10px; padding: 0 16px; border-top-left-radius: 12px; border-top-right-radius: 12px; @@ -1270,6 +1390,9 @@ pre.pygments [data-lang="bash"] .tok-s1 { .copy-icon p { margin-bottom: 0; color: var(--snippet-header-color) !important; + font-size: var(--font-size-xs); + text-transform: uppercase; + letter-spacing: 0.05em; } .icon-tip { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 502 502' xml:space='preserve'%3E%3Cpath d='M230.523 78.722c-35.583-.342-69.221 13.48-94.756 38.802-25.528 25.316-39.587 58.839-39.587 94.396 0 34.708 13.278 67.567 37.387 92.524 24 24.844 37.216 57.409 37.216 91.697v70.281c0 5.523 4.477 10 10 10h12.756C197.871 491.185 211.53 502 227.676 502s29.805-10.815 34.138-25.578h16.166c5.523 0 10-4.477 10-10v-70.275c0-34.627 12.99-66.961 36.576-91.044 24.522-25.04 38.027-58.133 38.027-93.185 0-35.38-13.723-68.697-38.64-93.812-24.902-25.1-58.079-39.086-93.42-39.384zM227.676 482c-4.787 0-9.076-2.17-11.936-5.578h23.872c-2.86 3.408-7.149 5.578-11.936 5.578zm40.304-25.578h-77.197v-37.125h77.197v37.125zm42.287-165.313c-27.269 27.844-42.287 65.148-42.287 105.039v3.15h-77.197v-3.156c0-39.5-15.211-77-42.832-105.593-20.488-21.208-31.771-49.133-31.771-78.629 0-30.183 11.958-58.663 33.67-80.194 21.72-21.538 50.338-33.226 80.505-33.005 61.882.521 112.228 51.301 112.228 113.197 0 29.789-11.477 57.912-32.316 79.191zM229.381 55.584c5.523 0 10-4.477 10-10V10c0-5.523-4.477-10-10-10s-10 4.477-10 10v35.584c0 5.523 4.477 10 10 10zM85.246 29.896a9.988 9.988 0 0 0 8.099 4.123 9.96 9.96 0 0 0 5.87-1.91c4.468-3.247 5.458-9.5 2.212-13.968l-7.108-9.783C91.073 3.89 84.82 2.9 80.351 6.146c-4.468 3.247-5.458 9.5-2.212 13.968l7.107 9.782zM124.729 84.239a9.988 9.988 0 0 0 8.099 4.123 9.96 9.96 0 0 0 5.87-1.91c4.468-3.246 5.458-9.5 2.212-13.968l-19.113-26.308c-3.246-4.468-9.499-5.459-13.968-2.212-4.468 3.246-5.458 9.5-2.212 13.968l19.112 26.307zM37.031 160.15l33.843 10.996a10.01 10.01 0 0 0 3.092.492c4.215 0 8.136-2.687 9.509-6.913 1.707-5.253-1.168-10.894-6.42-12.601l-33.843-10.996c-5.251-1.705-10.894 1.168-12.601 6.42-1.707 5.254 1.167 10.895 6.42 12.602zM84.808 260.51c-1.707-5.253-7.346-8.126-12.601-6.42l-33.843 10.996c-5.252 1.707-8.127 7.348-6.42 12.601 1.373 4.226 5.293 6.913 9.509 6.913a10.01 10.01 0 0 0 3.092-.492l33.843-10.996c5.252-1.708 8.126-7.349 6.42-12.602zM102.626 391.668c-4.467-3.246-10.721-2.255-13.968 2.212l-8.903 12.253c-3.246 4.468-2.256 10.722 2.212 13.968a9.952 9.952 0 0 0 5.87 1.91 9.99 9.99 0 0 0 8.099-4.123l8.903-12.253c3.246-4.467 2.256-10.72-2.213-13.967z'/%3E%3Cpath d='M134.544 347.736c-4.468-3.246-10.722-2.255-13.968 2.212l-8.845 12.175c-3.246 4.468-2.255 10.722 2.212 13.968a9.952 9.952 0 0 0 5.87 1.91 9.99 9.99 0 0 0 8.099-4.123l8.845-12.175c3.246-4.467 2.255-10.721-2.213-13.967zM338.347 336.895c-3.246-4.468-9.499-5.459-13.968-2.212-4.468 3.247-5.458 9.5-2.212 13.968l20.916 28.789a9.988 9.988 0 0 0 8.099 4.123 9.96 9.96 0 0 0 5.87-1.91c4.468-3.247 5.458-9.5 2.212-13.968l-20.917-28.79zM426.045 260.984l-33.843-10.997c-5.252-1.705-10.894 1.168-12.601 6.42-1.707 5.252 1.168 10.894 6.42 12.601l33.843 10.997a10.01 10.01 0 0 0 3.092.492c4.215 0 8.136-2.687 9.509-6.913 1.707-5.251-1.167-10.893-6.42-12.6zM471.39 130.367c-1.706-5.252-7.347-8.127-12.601-6.42l-14.678 4.769c-5.252 1.707-8.127 7.348-6.42 12.601 1.373 4.226 5.293 6.913 9.509 6.913a10.01 10.01 0 0 0 3.092-.492l14.678-4.769c5.252-1.708 8.126-7.349 6.42-12.602zM387.777 167.536a10.01 10.01 0 0 0 3.092-.492l25.994-8.446c5.252-1.707 8.127-7.348 6.42-12.601-1.707-5.252-7.347-8.127-12.601-6.42l-25.994 8.446c-5.252 1.707-8.127 7.348-6.42 12.601 1.374 4.225 5.294 6.912 9.509 6.912zM320.89 83.916a9.952 9.952 0 0 0 5.87 1.91 9.99 9.99 0 0 0 8.099-4.123l20.916-28.789c3.246-4.468 2.255-10.722-2.212-13.968-4.469-3.246-10.722-2.255-13.968 2.212l-20.916 28.789c-3.248 4.469-2.257 10.722 2.211 13.969zM288.349 135.549c-11.289-8.76-24.609-14.981-38.521-17.992-5.395-1.169-10.721 2.26-11.889 7.659-1.168 5.398 2.261 10.721 7.659 11.889 11.007 2.382 21.55 7.308 30.491 14.245a9.954 9.954 0 0 0 6.124 2.1 9.981 9.981 0 0 0 7.907-3.87c3.385-4.363 2.592-10.645-1.771-14.031zM202.914 119.066c-41.096 11.729-69.797 49.799-69.797 92.579 0 5.523 4.477 10 10 10s10-4.477 10-10c0-33.895 22.735-64.056 55.287-73.346 5.311-1.516 8.387-7.05 6.872-12.361-1.518-5.31-7.052-8.388-12.362-6.872z'/%3E%3C/svg%3E"); @@ -1296,11 +1419,29 @@ pre.pygments [data-lang="bash"] .tok-s1 { .main .admonitionblock { background-color: var(--color-primary-50); border: 1px solid var(--color-primary-100); - padding: 16px; - margin-top: 16px; - margin-bottom: 16px; + border-left: 3px solid var(--admon-note-accent); + padding: var(--space-3); + margin-top: var(--space-3); + margin-bottom: var(--space-4); border-radius: 12px; } +/* Admonition type differentiation */ +.main .admonitionblock.tip { + background-color: var(--admon-tip-bg); + border-color: var(--admon-tip-border); + border-left: 3px solid var(--admon-tip-accent); +} +.main .admonitionblock.warning, +.main .admonitionblock.caution { + background-color: var(--admon-warning-bg); + border-color: var(--admon-warning-border); + border-left: 3px solid var(--admon-warning-accent); +} +.main .admonitionblock.important { + background-color: var(--admon-important-bg); + border-color: var(--admon-important-border); + border-left: 3px solid var(--admon-important-accent); +} .main .admonitionblock table { margin-bottom: 0 !important; } @@ -1391,6 +1532,7 @@ pre.pygments [data-lang="bash"] .tok-s1 { .paragraph { font-size: 15px; font-weight: 400; + margin-bottom: var(--space-3); } .imageblock .content { background-color: #ffff; @@ -1701,3 +1843,110 @@ span.dot { margin-left: 5px; border-radius: 50%; } + +/* ======================================== + Responsive refinements + ======================================== */ + +@media (max-width: 480px) { + h1 { + font-size: 32px; + } + h2 { + font-size: 24px; + } + h3 { + font-size: 20px; + } + h4 { + font-size: 16px; + } + .content-wrapper { + padding: var(--space-3) !important; + } +} + +@media (max-width: 1024px) { + .content-wrapper #content { + max-width: 100%; + } + .content-wrapper .banner { + max-width: 100%; + } +} + +/* ======================================== + Print styles + ======================================== */ + +@media print { + .header, + .sidebar-wrapper, + .bd-links-wrapper, + .right-side-menu, + .bottom-nav-links, + .loader-wrapper, + .copy-icon, + .sidebar__control, + .sidebar-toggler, + .doclink, + .lightbox-modal, + .overlay { + display: none !important; + } + + .main .article-container { + width: 100% !important; + margin-left: 0 !important; + } + + .content-wrapper { + max-width: 100% !important; + padding: 0 !important; + } + + .content-wrapper #content { + max-width: 100%; + } + + body { + color: #000; + background: #fff !important; + font-size: 12pt; + line-height: 1.5; + } + + a { + color: #000; + text-decoration: underline; + } + + .main .listingblock, + .literalblock > .content pre { + border: 1px solid #ccc; + background: #f5f5f5 !important; + color: #333 !important; + color-scheme: light; + } + + .main .listingblock .content pre { + color: #333 !important; + } + + pre.pygments span { + color: #333 !important; + } + + .main .admonitionblock { + border: 1px solid #ccc; + background: #f9f9f9; + } + + .main .table-wrap { + border: 1px solid #ccc; + } + + .main img { + max-width: 100%; + } +} From 75d018a552a3c56b7f8d23b43f0f3f0b1ea7e610 Mon Sep 17 00:00:00 2001 From: Pierre-Alexandre Meyer Date: Thu, 12 Feb 2026 21:32:18 +0000 Subject: [PATCH 04/26] Iteration Signed-off-by: Pierre-Alexandre Meyer --- html5/_main_toc.html.slim | 6 +- stylesheets/kb.css | 312 ++++++++++++++++++++++++++++++++++--- userguide/index/index.adoc | 157 ++++++++++++------- 3 files changed, 393 insertions(+), 82 deletions(-) diff --git a/html5/_main_toc.html.slim b/html5/_main_toc.html.slim index 65f7c4f99..bbccac015 100644 --- a/html5/_main_toc.html.slim +++ b/html5/_main_toc.html.slim @@ -24,7 +24,7 @@ nav.sidebar-nav li a.nav-link href="/latest/premium_features.html" | Premium Capabilities - span.dot style="background-color: #7C3AE3;" + span.badge-premium Premium li .icon-title a.bd-toc-link.main-link role="button" @@ -279,7 +279,7 @@ nav.sidebar-nav .icon-title a.bd-toc-link.main-link role="button" | AWS - span.dot style="background-color: #7C3AE3;" + span.badge-premium Premium @@ -342,7 +342,7 @@ nav.sidebar-nav .icon-title a.bd-toc-link.main-link role="button" | Aviate - span.dot style="background-color: #7C3AE3;" + span.badge-premium Premium diff --git a/stylesheets/kb.css b/stylesheets/kb.css index c82ce6613..786f0037b 100644 --- a/stylesheets/kb.css +++ b/stylesheets/kb.css @@ -350,6 +350,10 @@ strong { .content-wrapper #content { max-width: var(--docs-content-max-width); } +/* Landing page needs wider content area for card grid */ +.content-wrapper #content:has(.landing-page) { + max-width: 960px; +} @media (min-width: 1020px) { .content-wrapper { padding: 0px 40px 40px 40px; @@ -370,7 +374,7 @@ strong { position: relative; display: flex; align-items: center; - padding: 56px 0px var(--space-5) 0px; + padding: 40px 0px var(--space-4) 0px; border-radius: 8px; max-width: var(--docs-content-max-width); } @@ -406,8 +410,8 @@ strong { display: flex; align-items: center; justify-content: space-between; - padding-top: 8px; - padding-bottom: 8px; + padding-top: 10px; + padding-bottom: 6px; cursor: pointer; } @@ -494,15 +498,16 @@ strong { } .main .sidebar-nav a.nav-link { - padding: 8px 12px; - margin-left: 8px; - font-size: 13.5px; + padding: 5px 10px; + margin-left: 6px; + font-size: 13px; + line-height: 1.4; transition: background-color 0.15s, color 0.15s; } .main .sidebar-nav a.nav-link:hover { color: var(--link-color); background-color: var(--color-gray-100); - border-radius: 10px; + border-radius: 6px; } .main .sidebar-nav a { color: var(--color); @@ -511,10 +516,10 @@ strong { .main .sidebar-nav a.bd-toc-link { padding-left: 12px; - font-weight: 400; - font-size: 14px; + font-weight: 500; + font-size: 13.5px; display: block; - color: var(--color); + color: var(--heading-color); transition-duration: .25s; transition-property: color; } @@ -774,8 +779,8 @@ pre.pygments .tok-o { .main .sidebar-nav > ul li ul { display: none; margin-left: 12px; - padding-bottom: 8px; - font-size: 14px; + padding-bottom: 4px; + font-size: 13px; border-left: 1px solid var(--color-gray-200); } @@ -786,20 +791,25 @@ pre.pygments .tok-o { .main .sidebar-nav > ul li ul li a { display: block; position: relative; - padding-left: 16px; - font-size: 14px; + padding-left: 14px; + font-size: 13px; } .main .sidebar-nav .list-item-active a { color: var(--link-color); - margin-bottom: 4px; + margin-bottom: 2px; background-color: var(--color-gray-100); - border-radius: 10px; - font-weight: 400; + border-radius: 6px; + font-weight: 500; } .main .sidebar-nav > .navbar-nav > li { margin-bottom: 0; + padding-bottom: 4px; + border-bottom: 1px solid var(--color-gray-200); +} +.main .sidebar-nav > .navbar-nav > li:last-child { + border-bottom: none; } .main .right-side-menu { @@ -892,7 +902,7 @@ ul.nav.navbar-nav { padding-left: 10px; border-left: solid 2px var(--link-color) !important; color: var(--link-color)!important; - font-weight: 600 !important; + font-weight: 500 !important; } .main .right-side-menu .navbar-nav .navbar-nav .nav-link.active{ @@ -1170,9 +1180,10 @@ pre.pygments .tok-ss { } .banner h1 { - font-size: clamp(32px, 5vw, 48px); - font-weight: 500; - line-height: 1.1; + font-size: clamp(28px, 4vw, 38px); + font-weight: 600; + line-height: 1.15; + letter-spacing: -0.02em; } .banner .absolute-figure { @@ -1244,7 +1255,8 @@ pre.pygments .tok-ss { .card { height: 100%; background-color: var(--background-color); - border-color: var(--color-primary-50); + border-color: var(--color-gray-200); + border-radius: 8px; } .card-wrapper .card-text { min-height: 80px; @@ -1258,6 +1270,34 @@ pre.pygments .tok-ss { padding: 1rem 0.25rem; } +/* Card-group layout inside content area (e.g. AWS page) */ +.content-wrapper .card-group { + display: flex; + flex-wrap: wrap; + gap: var(--space-3); +} +.content-wrapper .card-group > .card { + flex: 1 1 240px; + max-width: 100%; + border: 1px solid var(--color-gray-200); + border-radius: 8px; +} +.content-wrapper .card-group > .card + .card { + border-left: 1px solid var(--color-gray-200); +} +.content-wrapper .card-group .card-body { + padding: var(--space-3); +} +.content-wrapper .card-group .card-title { + font-size: 16px; + font-weight: 600; + margin-bottom: var(--space-2); +} +.content-wrapper .card-group .btn { + font-size: 13px; + padding: 6px 14px; +} + pre code { color: var(--snippet-body-color); } @@ -1844,6 +1884,234 @@ span.dot { border-radius: 50%; } +/* Premium badge for sidebar nav */ +.badge-premium { + display: inline-flex; + align-items: center; + margin-left: 8px; + padding: 1px 7px; + font-size: 10px; + font-weight: 600; + letter-spacing: 0.03em; + line-height: 18px; + color: #6D28D9; + background: linear-gradient(135deg, #EDE9FE, #DDD6FE); + border: 1px solid #C4B5FD; + border-radius: 4px; + white-space: nowrap; + vertical-align: middle; + text-transform: uppercase; +} +[data-theme="dark"] .badge-premium { + color: #C4B5FD; + background: linear-gradient(135deg, #2E1065, #3B1A8E); + border-color: #5B21B6; +} + +/* ======================================== + Landing page + ======================================== */ + +.landing-page { + max-width: 900px; +} + +/* Hero */ +.landing-hero { + padding: var(--space-5) 0 var(--space-6); + border-bottom: 1px solid var(--color-gray-200); +} +.landing-hero-subtitle { + font-size: 17px; + font-weight: 500; + color: var(--link-color); + margin-bottom: var(--space-2); + letter-spacing: -0.01em; +} +.landing-hero-desc { + font-size: 16px; + line-height: 1.6; + color: var(--color); + max-width: 600px; + margin-bottom: var(--space-4); +} +.landing-hero-actions { + display: flex; + gap: 12px; + flex-wrap: wrap; +} +.landing-btn { + padding: 10px 24px; + font-size: 14px; + font-weight: 500; + border-radius: 8px; + text-decoration: none !important; + transition: background-color 0.15s, border-color 0.15s; +} +.landing-btn-outline { + background-color: transparent; + color: var(--color) !important; + border: 1px solid var(--color-gray-200); +} +.landing-btn-outline:hover { + background-color: var(--color-gray-50); + border-color: var(--color-base-white); + color: var(--color) !important; +} + +/* Section headings */ +.landing-section { + padding: var(--space-6) 0 0; +} +.landing-section-title { + font-size: 20px; + font-weight: 600; + color: var(--heading-color); + margin-bottom: var(--space-4); + letter-spacing: -0.01em; +} + +/* Card grid */ +.landing-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} +.landing-grid-2 { + grid-template-columns: repeat(2, 1fr); +} +@media (max-width: 768px) { + .landing-grid { + grid-template-columns: 1fr; + } + .landing-grid-2 { + grid-template-columns: 1fr; + } +} +@media (min-width: 769px) and (max-width: 1024px) { + .landing-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +/* Cards */ +.landing-card { + display: block; + padding: 20px; + border: 1px solid var(--color-gray-200); + border-radius: 10px; + background-color: var(--background-color); + text-decoration: none !important; + color: var(--color) !important; + transition: border-color 0.15s, box-shadow 0.15s; +} +.landing-card:hover { + border-color: var(--link-color); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); + color: var(--color) !important; +} +.landing-card-icon { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 8px; + background-color: var(--color-primary-50); + color: var(--link-color); + margin-bottom: 14px; +} +.landing-card-icon svg { + width: 20px; + height: 20px; +} +.landing-card-title { + font-size: 15px; + font-weight: 600; + color: var(--heading-color); + margin-bottom: 6px; + line-height: 1.3; +} +.landing-card-desc { + font-size: 13.5px; + line-height: 1.55; + color: var(--color); + margin-bottom: 0; +} + +/* Premium variant */ +.landing-card-premium { + border-color: #C4B5FD; + background: linear-gradient(180deg, var(--background-color) 60%, #FAF5FF); +} +[data-theme="dark"] .landing-card-premium { + border-color: #5B21B6; + background: linear-gradient(180deg, var(--background-color) 60%, #1E0A3C); +} +.landing-card-premium:hover { + border-color: #8B5CF6; +} +.landing-card-header { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 8px; +} +.landing-card-header .landing-card-title { + margin-bottom: 0; +} +.landing-card-header .badge-premium { + margin-left: 0; +} + +/* Tutorial links grid */ +.landing-links-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0; + border: 1px solid var(--color-gray-200); + border-radius: 10px; + overflow: hidden; + background-color: var(--background-color); +} +@media (max-width: 768px) { + .landing-links-grid { + grid-template-columns: 1fr; + } +} +@media (min-width: 769px) and (max-width: 1024px) { + .landing-links-grid { + grid-template-columns: repeat(2, 1fr); + } +} +.landing-link { + display: flex; + align-items: center; + padding: 14px 18px; + font-size: 14px; + font-weight: 400; + color: var(--color) !important; + text-decoration: none !important; + border-bottom: 1px solid var(--color-gray-200); + border-right: 1px solid var(--color-gray-200); + transition: background-color 0.15s, color 0.15s; +} +.landing-link:hover { + background-color: var(--color-gray-50); + color: var(--link-color) !important; +} +.landing-link::before { + content: ''; + display: inline-block; + width: 6px; + height: 6px; + border-right: 1.5px solid var(--link-color); + border-top: 1.5px solid var(--link-color); + transform: rotate(45deg); + margin-right: 10px; + flex-shrink: 0; +} + /* ======================================== Responsive refinements ======================================== */ diff --git a/userguide/index/index.adoc b/userguide/index/index.adoc index 857e3e664..eb5dffa52 100644 --- a/userguide/index/index.adoc +++ b/userguide/index/index.adoc @@ -1,68 +1,111 @@ = Kill Bill Documentation ++++ -
-
-
-
-
-
-
What is Kill Bill?
-

- Not sure what Kill Bill is? Want to understand how it - compares to other SaaS offerings? -

-
- -
-
+ -
- -
-

- With Kill Bill, you can manage your customers' subscriptions in a - simple and flexible way: the system will automatically take care - of generating recurring invoices and triggering payments. -

+ + + +
+

Tutorials & Guides

+ +
+ + +
+

Watch: Getting Started

- +
-
-
+ + + ++++ From 11daf5003a65b65d2c69724eed5d40f52f7c54f8 Mon Sep 17 00:00:00 2001 From: Pierre-Alexandre Meyer Date: Fri, 13 Feb 2026 08:13:07 +0000 Subject: [PATCH 05/26] Iteration Signed-off-by: Pierre-Alexandre Meyer --- .gitignore | 4 ++- html5/_main_toc.html.slim | 14 ++++---- javascripts/kb.js | 35 +++++++++++++++---- stylesheets/kb.css | 21 ++++++----- userguide/analytics/userguide_analytics.adoc | 2 +- .../aviate-custom-invoice-sequencing.adoc | 2 +- userguide/aviate/aviate-health.adoc | 4 +-- userguide/aviate/aviate-metering.adoc | 4 +-- userguide/aviate/aviate-tax-tutorial.adoc | 4 +-- userguide/aviate/aviate-tax.adoc | 2 +- .../aviate/aviate-usage-ai-tutorial.adoc | 18 +++++----- .../getting-started/getting_started.adoc | 6 ++-- .../quick_start_with_kaui.adoc | 4 +-- .../quick_start_with_kb_api.adoc | 18 +++++----- .../getting-started/what_is_kill_bill.adoc | 6 ++-- userguide/glossary/Kill-Bill-Glossary.adoc | 2 +- userguide/index/index.adoc | 6 ++-- userguide/kaui/includes/catalog.adoc | 4 +-- userguide/kaui/includes/custom-fields.adoc | 4 +-- userguide/kaui/includes/tags.adoc | 8 ++--- userguide/kaui/includes/tenants.adoc | 2 +- .../kaui/includes/translation-files.adoc | 2 +- userguide/payment/includes/payment-flows.adoc | 2 +- userguide/payment/userguide_payment.adoc | 2 +- ...llbill-configuration-properties-table.adoc | 2 +- .../platform/userguide_configuration.adoc | 2 +- .../subscription/userguide_subscription.adoc | 2 +- userguide/tutorials/catalog-examples.adoc | 30 ++++++++-------- userguide/tutorials/invoice_examples.adoc | 30 ++++++++-------- userguide/tutorials/invoice_subsystem.adoc | 2 +- userguide/tutorials/invoice_templates.adoc | 6 ++-- userguide/tutorials/kill_bill_events.adoc | 2 +- userguide/tutorials/payment_plugin.adoc | 6 ++-- userguide/tutorials/push_notifications.adoc | 12 +++---- userguide/tutorials/stripe_plugin.adoc | 2 +- 35 files changed, 149 insertions(+), 123 deletions(-) diff --git a/.gitignore b/.gitignore index ed28fe615..f757e5b30 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,6 @@ latest package.json package-lock.json page.sh -vendor \ No newline at end of file +vendor +assessment.md +tickets.md diff --git a/html5/_main_toc.html.slim b/html5/_main_toc.html.slim index bbccac015..59b5a845b 100644 --- a/html5/_main_toc.html.slim +++ b/html5/_main_toc.html.slim @@ -130,7 +130,7 @@ nav.sidebar-nav ul.nav.navbar-nav li.bd-sidenav-active - a.nav-link href="http://killbill.github.io/slate" onclick=("getOutboundLink('http://killbill.github.io/slate'); return false;") + a.nav-link href="https://apidocs.killbill.io" onclick=("getOutboundLink('https://apidocs.killbill.io'); return false;") | REST API Reference li a.nav-link href="/latest/swagger_documentation.html" @@ -221,19 +221,19 @@ nav.sidebar-nav a.nav-link href="/latest/java_client.html" | Java li - a.nav-link href="http://github.com/killbill/killbill-client-ruby" onclick=("getOutboundLink('http://github.com/killbill/killbill-client-ruby'); return false;") + a.nav-link href="https://github.com/killbill/killbill-client-ruby" onclick=("getOutboundLink('https://github.com/killbill/killbill-client-ruby'); return false;") | Ruby li - a.nav-link href="http://github.com/killbill/killbill-client-php" onclick=("getOutboundLink('http://github.com/killbill/killbill-client-php'); return false;") + a.nav-link href="https://github.com/killbill/killbill-client-php" onclick=("getOutboundLink('https://github.com/killbill/killbill-client-php'); return false;") | PHP li - a.nav-link href="http://github.com/killbill/killbill-client-js" onclick=("getOutboundLink('http://github.com/killbill/killbill-client-js'); return false;") + a.nav-link href="https://github.com/killbill/killbill-client-js" onclick=("getOutboundLink('https://github.com/killbill/killbill-client-js'); return false;") | Node.js li - a.nav-link href="http://github.com/killbill/killbill-client-python" onclick=("getOutboundLink('http://github.com/killbill/killbill-client-python'); return false;") + a.nav-link href="https://github.com/killbill/killbill-client-python" onclick=("getOutboundLink('https://github.com/killbill/killbill-client-python'); return false;") | Python li - a.nav-link href="http://github.com/killbill/kbcli" onclick=("getOutboundLink('http://github.com/killbill/kbcli'); return false;") + a.nav-link href="https://github.com/killbill/kbcli" onclick=("getOutboundLink('https://github.com/killbill/kbcli'); return false;") | KillBill Go li .icon-title @@ -248,7 +248,7 @@ nav.sidebar-nav | Demo li a.nav-link href="/latest/features.html" - | Features List + | Platform Capabilities li a.nav-link href="/latest/faq.html" | Technical FAQs diff --git a/javascripts/kb.js b/javascripts/kb.js index d92772e5b..f360a1cfe 100644 --- a/javascripts/kb.js +++ b/javascripts/kb.js @@ -20,12 +20,19 @@ setTimeout(function () { }) function copyToClipboard(text) { - let sampleTextarea = document.createElement("textarea"); - document.body.appendChild(sampleTextarea); - sampleTextarea.value = text; - sampleTextarea.select(); - document.execCommand("copy"); - document.body.removeChild(sampleTextarea); + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(text).catch(function () {}); + } else { + // Fallback for older browsers/non-HTTPS contexts + let textarea = document.createElement('textarea'); + textarea.value = text; + textarea.style.position = 'fixed'; + textarea.style.opacity = '0'; + document.body.appendChild(textarea); + textarea.select(); + try { document.execCommand('copy'); } catch (e) {} + document.body.removeChild(textarea); + } } $('.content-wrapper h2 a, .content-wrapper h3 a, .content-wrapper h4 a').on('click', function () { @@ -36,7 +43,16 @@ setTimeout(function () { $('.content-wrapper .note td.icon').append(` `); - $('.content pre').parent('.content').prepend('

'); + $('.content pre').each(function () { + let codeEl = $(this).find('code'); + let lang = codeEl.attr('data-lang') + || (codeEl.attr('class') || '').match(/language-(\w+)/)?.[1] + || ''; + let label = lang ? lang.toUpperCase() : ''; + $(this).parent('.content').prepend( + '

' + label + '

' + ); + }); $('.copy-icon svg').on('click', function () { let that = this; @@ -152,4 +168,9 @@ if (nextNav?.link) { } } else { $('#next-nav-link').css('display', 'none'); +} + +// Hide prev/next navigation on landing page +if (document.querySelector('.landing-page')) { + $('.bottom-nav-links').hide(); } \ No newline at end of file diff --git a/stylesheets/kb.css b/stylesheets/kb.css index 786f0037b..6b7f8da8b 100644 --- a/stylesheets/kb.css +++ b/stylesheets/kb.css @@ -857,7 +857,7 @@ ul.nav.navbar-nav { } .main .right-side-menu > .navbar-nav:before { - content: "In this document"; + content: "On this page"; display: block; margin-bottom: var(--space-4); font-weight: 500; @@ -1127,13 +1127,13 @@ pre.pygments .tok-ss { } /* Section separators between major sections */ .main #content > .sect1 + .sect1 { - border-top: 1px solid var(--color-gray-200); padding-top: var(--space-6); } .content-wrapper h2 a, .content-wrapper h3 a, .content-wrapper h4 a { - display: none; + opacity: 0; margin-left: 5px; + transition: opacity 0.15s ease; } .content-wrapper h2 a, .content-wrapper h3 a, .content-wrapper h4 a svg{ fill: var(--color); @@ -1144,7 +1144,7 @@ pre.pygments .tok-ss { } .content-wrapper h2:hover a, .content-wrapper h3:hover a, .content-wrapper h4:hover a { - display: inline; + opacity: 1; } .breadcrumbs-wrapper { @@ -1512,7 +1512,7 @@ pre.pygments [data-lang="bash"] .tok-s1 { position: fixed; top: 50%; left: 50%; - background-color: #ebebeb; + background-color: transparent; padding: 20px; transform: translate(-50%, -50%); z-index: 100; @@ -1542,13 +1542,16 @@ pre.pygments [data-lang="bash"] .tok-s1 { } #close-ligtbox { position: absolute; - right: -35px; - top: -35px; + right: 10px; + top: -45px; display: block; width: 30px; - font-size: 36px; + font-size: 28px; border-radius: 8px; cursor: pointer; + color: rgba(255, 255, 255, 0.8); +} +#close-ligtbox:hover { color: #fff; } @media (max-width: 1023px) { @@ -1562,7 +1565,7 @@ pre.pygments [data-lang="bash"] .tok-s1 { .overlay { display: none; position: fixed; - background-color: rgba(0,0,0,.5); + background-color: rgba(0, 0, 0, 0.85); left: 0; top: 0; right: 0; diff --git a/userguide/analytics/userguide_analytics.adoc b/userguide/analytics/userguide_analytics.adoc index aac67666d..4151d2261 100644 --- a/userguide/analytics/userguide_analytics.adoc +++ b/userguide/analytics/userguide_analytics.adoc @@ -61,7 +61,7 @@ You can configure the following properties related to the analytics plugin in th *Note:* All the properties specified above are optional and the analytics plugin uses suitable defaults in case they are not specified. We however encourage you use different notification queue tables by specifying the `org.killbill.notificationq.analytics.tableName` and `org.killbill.notificationq.analytics.historyTableName` properties. -In addition, the analytics plugin also allows some optional https://docs.killbill.io/latest/userguide_configuration.html#_per_tenant_properties[tenant level] configuration. This can be done by executing the https://killbill.github.io/slate/tenant.html#add-a-per-tenant-configuration-for-a-plugin[per-tenant configuration] endpoint as follows: +In addition, the analytics plugin also allows some optional https://docs.killbill.io/latest/userguide_configuration.html#_per_tenant_properties[tenant level] configuration. This can be done by executing the https://apidocs.killbill.io/tenant.html#add-a-per-tenant-configuration-for-a-plugin[per-tenant configuration] endpoint as follows: [source,bash] ---- diff --git a/userguide/aviate/aviate-custom-invoice-sequencing.adoc b/userguide/aviate/aviate-custom-invoice-sequencing.adoc index 0f6275ed2..8f489a14a 100644 --- a/userguide/aviate/aviate-custom-invoice-sequencing.adoc +++ b/userguide/aviate/aviate-custom-invoice-sequencing.adoc @@ -23,7 +23,7 @@ com.killbill.billing.plugin.aviate.enableCustomInvoiceSequencing=true === Tenant-level Configuration -In addition, the Aviate Custom Invoicing feature requires some tenant-level configuration. This can be done by executing the https://killbill.github.io/slate/tenant.html#add-a-per-tenant-configuration-for-a-plugin[per-tenant configuration] endpoint as follows: +In addition, the Aviate Custom Invoicing feature requires some tenant-level configuration. This can be done by executing the https://apidocs.killbill.io/tenant.html#add-a-per-tenant-configuration-for-a-plugin[per-tenant configuration] endpoint as follows: [source, bash] ---- diff --git a/userguide/aviate/aviate-health.adoc b/userguide/aviate/aviate-health.adoc index 47afe5e7d..54fa0e7a6 100644 --- a/userguide/aviate/aviate-health.adoc +++ b/userguide/aviate/aviate-health.adoc @@ -33,7 +33,7 @@ As mentioned earlier, Aviate Health exposes endpoints that allow monitoring the == Aviate Metrics -The Aviate plugin provides a https://killbill.github.io/slate/aviate-health-apis.html#retrieve-metrics[Retrieve Metrics] endpoint that can be used to assess the health of the system. +The Aviate plugin provides a https://apidocs.killbill.io/aviate-health-apis.html#retrieve-metrics[Retrieve Metrics] endpoint that can be used to assess the health of the system. This section provides some insights into the metrics that can be retrieved via this endpoint. @@ -149,7 +149,7 @@ defined in sources [RuntimeConfiguration, EnvironmentVariables] - using value from 'EnvironmentVariables': '11s'` -To make it easier to understand the runtime values of these properties, Kill Bill provides the https://killbill.github.io/slate/aviate-health.html#retrieve-runtime-configuration[/v1/health/config] endpoint. +To make it easier to understand the runtime values of these properties, Kill Bill provides the https://apidocs.killbill.io/aviate-health.html#retrieve-runtime-configuration[/v1/health/config] endpoint. This endpoint displays the effective configuration currently in use along with information about which source each property value was derived from. diff --git a/userguide/aviate/aviate-metering.adoc b/userguide/aviate/aviate-metering.adoc index e3e436077..cbe2498b1 100644 --- a/userguide/aviate/aviate-metering.adoc +++ b/userguide/aviate/aviate-metering.adoc @@ -6,7 +6,7 @@ include::{sourcedir}/aviate/includes/aviate-card.adoc[] The Aviate plugin offers metering capabilities. The https://apidocs.killbill.io/usage[Kill Bill core usage APIs] support recording rolled-up usage data, but aggregation must be performed outside Kill Bill. With the introduction of the metering feature, aggregation can now occur directly within Kill Bill by using the metering APIs. Thus, this feature allows users to be charged based on aggregated units seamlessly. -The Aviate Metering feature introduces the concept of a https://killbill.github.io/slate/aviate-metering-apis.html#billingmeter[BillingMeter] and a https://killbill.github.io/slate/aviate-metering-apis.html#usageevent[UsageEvent]. A `BillingMeter` encapsulates information about how usage points should be aggregated - e.g. sum all points within a specific period. A `UsageEvent` represents a single usage point. Each `UsageEvent` has an associated `BillingMeter`. The `UsageEvents` are then aggregated based on the aggregation type specified in the associated `BillingMeter`. +The Aviate Metering feature introduces the concept of a https://apidocs.killbill.io/aviate-metering-apis.html#billingmeter[BillingMeter] and a https://apidocs.killbill.io/aviate-metering-apis.html#usageevent[UsageEvent]. A `BillingMeter` encapsulates information about how usage points should be aggregated - e.g. sum all points within a specific period. A `UsageEvent` represents a single usage point. Each `UsageEvent` has an associated `BillingMeter`. The `UsageEvents` are then aggregated based on the aggregation type specified in the associated `BillingMeter`. == Getting Started with Aviate Metering @@ -29,7 +29,7 @@ Refer to the https://docs.killbill.io/latest/userguide_configuration.html[__Kill === Using Metering APIs -Once the aviate plugin has been installed and the metering feature is enabled, you can start using the Aviate Metering APIs. These APIs enable creation of billing meters and allow to record raw (non aggregated) usage points. These APIs replace the https://killbill.github.io/slate/usage.html#record-usage-for-a-subscription[Kill Bill usage APIs]: Users should either use existing Kill Bill usage APIs (to record aggregated usage points) or use the Aviate metering APIs discussed in this section. For more details about these APIs, please refer to our https://apidocs.killbill.io/aviate-metering[api docs]. +Once the aviate plugin has been installed and the metering feature is enabled, you can start using the Aviate Metering APIs. These APIs enable creation of billing meters and allow to record raw (non aggregated) usage points. These APIs replace the https://apidocs.killbill.io/usage.html#record-usage-for-a-subscription[Kill Bill usage APIs]: Users should either use existing Kill Bill usage APIs (to record aggregated usage points) or use the Aviate metering APIs discussed in this section. For more details about these APIs, please refer to our https://apidocs.killbill.io/aviate-metering[api docs]. Note that in the current implementation, the caller should ensure that all usage points for a specific subscription are submitted sequentially (i.e., must not be submitted concurrently). diff --git a/userguide/aviate/aviate-tax-tutorial.adoc b/userguide/aviate/aviate-tax-tutorial.adoc index b7df48b03..d34bc94ea 100644 --- a/userguide/aviate/aviate-tax-tutorial.adoc +++ b/userguide/aviate/aviate-tax-tutorial.adoc @@ -19,7 +19,7 @@ You will need: We start by creating a tenant `tax-scenario`. -Use the standard https://killbill.github.io/slate/tenant.html#create-a-tenant[Create Tenant] Kill Bill API: +Use the standard https://apidocs.killbill.io/tenant.html#create-a-tenant[Create Tenant] Kill Bill API: [source,bash] ----- @@ -145,7 +145,7 @@ curl -v \ === Step 1: Create a new account -Use the standard Kill Bill https://killbill.github.io/slate/account.html#create-an-account[Create Account] API: +Use the standard Kill Bill https://apidocs.killbill.io/account.html#create-an-account[Create Account] API: [source,bash] ----- diff --git a/userguide/aviate/aviate-tax.adoc b/userguide/aviate/aviate-tax.adoc index 0439f3e7a..487299ab4 100644 --- a/userguide/aviate/aviate-tax.adoc +++ b/userguide/aviate/aviate-tax.adoc @@ -38,7 +38,7 @@ In addition, the Aviate Tax feature requires some tenant-level configuration. T ++++ -Alternatively, you can also execute the https://killbill.github.io/slate/tenant.html#add-a-per-tenant-configuration-for-a-plugin[per-tenant configuration] endpoint as follows: +Alternatively, you can also execute the https://apidocs.killbill.io/tenant.html#add-a-per-tenant-configuration-for-a-plugin[per-tenant configuration] endpoint as follows: [source, bash] ---- diff --git a/userguide/aviate/aviate-usage-ai-tutorial.adoc b/userguide/aviate/aviate-usage-ai-tutorial.adoc index b02439822..55acf67b7 100644 --- a/userguide/aviate/aviate-usage-ai-tutorial.adoc +++ b/userguide/aviate/aviate-usage-ai-tutorial.adoc @@ -27,7 +27,7 @@ You will need: We start by creating a tenant `usage-scenario`. -Use the standard https://killbill.github.io/slate/tenant.html#create-a-tenant[Create Tenant] Kill Bill API: +Use the standard https://apidocs.killbill.io/tenant.html#create-a-tenant[Create Tenant] Kill Bill API: [source,bash] ----- @@ -45,7 +45,7 @@ A BillingMeter defines how usage points are filtered and aggregated. Before crea For reference, this uses the https://docs.killbill.io/latest/aviate-metering[aviate metering capabilities]. -Use the https://killbill.github.io/slate/aviate-metering.html#create-billing-meter[Create Billing Meter] API. +Use the https://apidocs.killbill.io/aviate-metering.html#create-billing-meter[Create Billing Meter] API. [source,bash] ----- @@ -96,7 +96,7 @@ For reference, this uses the https://docs.killbill.io/latest/aviate-catalog-plug The full payload and API call can be seen below: -Use the https://killbill.github.io/slate/aviate-catalog.html#create-plan-product-pricelist[Create Plan, Product, Pricelist] API: +Use the https://apidocs.killbill.io/aviate-catalog.html#create-plan-product-pricelist[Create Plan, Product, Pricelist] API: [source,bash] ----- @@ -113,7 +113,7 @@ http://127.0.0.1:8080/plugins/aviate-plugin/v1/catalog/inputData === Step 1: Create an account -Use the standard Kill Bill https://killbill.github.io/slate/account.html#create-an-account[Create Account] API: +Use the standard Kill Bill https://apidocs.killbill.io/account.html#create-an-account[Create Account] API: [source,bash] ----- @@ -128,7 +128,7 @@ curl -v -X POST -u admin:password \ === Step 2: Add a payment method -Use the standard Kill Bill https://killbill.github.io/slate/account.html#add-a-payment-method[Add Payment Method] API: +Use the standard Kill Bill https://apidocs.killbill.io/account.html#add-a-payment-method[Add Payment Method] API: [source,bash] ----- @@ -168,7 +168,7 @@ Finally, we also set some expiration dates on these credits as indicated in the For reference, this uses the https://docs.killbill.io/latest/aviate-wallet[aviate wallet capabilities] -Use the https://killbill.github.io/slate/aviate-wallet.html#create-a-wallet[Create Wallet] API: +Use the https://apidocs.killbill.io/aviate-wallet.html#create-a-wallet[Create Wallet] API: [source,bash] ----- @@ -189,7 +189,7 @@ Note that we see a `WALLET_PAYMENT_FAILED` status because we did not pass the qu For reference, this uses the https://docs.killbill.io/latest/aviate-metering[aviate metering capabilities] -Use the https://killbill.github.io/slate/aviate-metering.html#submit-usage-events[Submit Usage Event] API: +Use the https://apidocs.killbill.io/aviate-metering.html#submit-usage-events[Submit Usage Event] API: [source,bash] ----- @@ -248,7 +248,7 @@ curl -v -u admin:password \ === Step 1: Set default payment method -Use the standard Kill Bill https://killbill.github.io/slate/account.html#set-the-default-payment-method[Set Default Payment Method] API: +Use the standard Kill Bill https://apidocs.killbill.io/account.html#set-the-default-payment-method[Set Default Payment Method] API: [source,bash] ----- @@ -261,7 +261,7 @@ curl -v -X PUT -u admin:password \ === Step 2: Retry invoice payment -Use the standard Kill Bill https://killbill.github.io/slate/invoice.html#trigger-a-payment-for-an-invoice[Trigger Payment for an Invoice] API: +Use the standard Kill Bill https://apidocs.killbill.io/invoice.html#trigger-a-payment-for-an-invoice[Trigger Payment for an Invoice] API: [source,bash] ----- diff --git a/userguide/getting-started/getting_started.adoc b/userguide/getting-started/getting_started.adoc index 5ebbd76e5..f1a075538 100644 --- a/userguide/getting-started/getting_started.adoc +++ b/userguide/getting-started/getting_started.adoc @@ -28,11 +28,11 @@ include::{sourcedir}/getting-started/includes/tomcat.adoc[] Create your first tenant, simple catalog, account, payment method, and subscription by following the steps in the either of these guides: -* https://docs.killbill.io/latest/quick_start_with_kaui.html[_Quick Start with Kaui_] +* https://docs.killbill.io/latest/quick_start_with_kaui.html[_Quick Start with Kaui_] * https://docs.killbill.io/latest/quick_start_with_kb_api.html[_Quick Start with the Kill Bill API_] -Explore our full https://killbill.github.io/slate/[API documentation]. +Explore our full https://apidocs.killbill.io/[API documentation]. We also have lots of examples in our https://github.com/killbill/killbill-integration-tests[Ruby] and https://github.com/killbill/killbill/tree/master/profiles/killbill/src/test/java/org/killbill/billing/jaxrs[Java] integration tests. -For support along the way, do *not* open GitHub issues. Instead, reach out to our https://groups.google.com/forum/#!forum/killbilling-users[Google Group]. Our +++GitHub sponsors+++ can also jump on our VIP community Slack channel. +For support along the way, do *not* open GitHub issues. Instead, reach out to our https://groups.google.com/forum/#!forum/killbilling-users[Google Group]. Our https://github.com/sponsors/killbill[GitHub sponsors] can also jump on our VIP community Slack channel. diff --git a/userguide/getting-started/quick_start_with_kaui.adoc b/userguide/getting-started/quick_start_with_kaui.adoc index 2875fd66d..8900d3764 100644 --- a/userguide/getting-started/quick_start_with_kaui.adoc +++ b/userguide/getting-started/quick_start_with_kaui.adoc @@ -15,7 +15,7 @@ Make sure you have installed Kill Bill and Kaui and launched them per the https: == Additional Resources -* https://killbill.github.io/slate[_API Reference_] +* https://apidocs.killbill.io[_API Reference_] * https://docs.killbill.io/latest/userguide_kaui.html[_Kaui Guide_] @@ -55,7 +55,7 @@ The Kill Bill https://docs.killbill.io/latest/Kill-Bill-Glossary.html#catalog[ca For this tutorial, instead of starting with the XML catalog, you'll learn how to create a simple catalog in Kaui and configure it with two plans. [NOTE] -*Note:* The simple catalog supports a _subset_ of the regular XML catalog features and isn't intended to serve as a catalog in production. For more details on the simple catalog, see the https://killbill.github.io/slate/#catalog-simple-plan["Simple Plan"] section in the _API Reference_. +*Note:* The simple catalog supports a _subset_ of the regular XML catalog features and isn't intended to serve as a catalog in production. For more details on the simple catalog, see the https://apidocs.killbill.io/#catalog-simple-plan["Simple Plan"] section in the _API Reference_. To create the simple catalog and two plans: diff --git a/userguide/getting-started/quick_start_with_kb_api.adoc b/userguide/getting-started/quick_start_with_kb_api.adoc index f0ac4d386..24b2ccac8 100644 --- a/userguide/getting-started/quick_start_with_kb_api.adoc +++ b/userguide/getting-started/quick_start_with_kb_api.adoc @@ -15,7 +15,7 @@ Make sure you have installed Kill Bill and Kaui and launched them per the https: == Additional Resources -* https://killbill.github.io/slate[_API Reference_] +* https://apidocs.killbill.io[_API Reference_] * https://docs.killbill.io/latest/userguide_kaui.html[_Kaui Guide_] @@ -26,7 +26,7 @@ Make sure you have installed Kill Bill and Kaui and launched them per the https: Kill Bill supports multi-tenancy, where each https://docs.killbill.io/latest/Kill-Bill-Glossary.html#tenant[tenant^] has its own data, configuration, and so forth. This section explains how to create a tenant via the Kill Bill API. -For more information, see the https://killbill.github.io/slate/?java#tenant-create-a-tenant[Create a Tenant] endpoint. +For more information, see the https://apidocs.killbill.io/?java#tenant-create-a-tenant[Create a Tenant] endpoint. **Example Request** @@ -203,10 +203,10 @@ no content The Kill Bill https://docs.killbill.io/latest/Kill-Bill-Glossary.html#catalog[catalog^] contains https://docs.killbill.io/latest/Kill-Bill-Glossary.html#products[products^] and https://docs.killbill.io/latest/Kill-Bill-Glossary.html#plans[plans^] definitions. This XML configuration file is really powerful and offers various options for handling https://docs.killbill.io/latest/Kill-Bill-Glossary.html#trial_phase[trials^], https://docs.killbill.io/latest/Kill-Bill-Glossary.html#addons[add-ons^], https://docs.killbill.io/latest/Kill-Bill-Glossary.html#upgrade[upgrades^] / https://docs.killbill.io/latest/Kill-Bill-Glossary.html#downgrade[downgrades^], and so forth. (For more information on the Kill Bill catalog, see the https://docs.killbill.io/latest/userguide_subscription.html#components-catalog[Catalog] section in the _Subscription Billing_ guide.) -For this tutorial, instead of starting with the XML catalog, you'll learn how to create a simple catalog using the API as well as adding one plan. You can find more information on the https://killbill.github.io/slate/#catalog-simple-plan[Simple Plan] endpoint in the API. +For this tutorial, instead of starting with the XML catalog, you'll learn how to create a simple catalog using the API as well as adding one plan. You can find more information on the https://apidocs.killbill.io/#catalog-simple-plan[Simple Plan] endpoint in the API. [NOTE] -*Note:* The simple catalog supports a _subset_ of the regular XML catalog features and isn't intended to serve as a catalog in production. For more details on the simple catalog, see the https://killbill.github.io/slate/#catalog-simple-plan["Simple Plan"] section in the _API Reference_. +*Note:* The simple catalog supports a _subset_ of the regular XML catalog features and isn't intended to serve as a catalog in production. For more details on the simple catalog, see the https://apidocs.killbill.io/#catalog-simple-plan["Simple Plan"] section in the _API Reference_. ++++