mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
Add Vercel deployment config for webview-app (#1880)
* add vercel config * update config * fix * make monorepo private for vercel * set node version * fix install * test * fix vercel webapp deploys * fix build command * better skip * prettier * format * fix deploy
This commit is contained in:
@@ -257,7 +257,10 @@ export const generateKycRegisterInput = async (
|
||||
// Use raw bytes directly — deserialize→reserialize strips the namespace prefix
|
||||
// from id_type, producing different bytes than the TEE signed.
|
||||
const raw = Buffer.from(applicantInfoBase64, 'base64');
|
||||
const dataPadded = [...Array.from(raw, (b) => Number(b)), ...new Array(Math.max(0, KYC_MAX_LENGTH - raw.length)).fill(0)];
|
||||
const dataPadded = [
|
||||
...Array.from(raw, (b) => Number(b)),
|
||||
...new Array(Math.max(0, KYC_MAX_LENGTH - raw.length)).fill(0),
|
||||
];
|
||||
|
||||
const kycRegisterInput: KycRegisterInput = {
|
||||
data_padded: dataPadded,
|
||||
|
||||
@@ -19,7 +19,10 @@ export function generateKycRegisterInputs(
|
||||
// Use raw bytes directly — deserialize→reserialize strips the namespace prefix
|
||||
// from id_type, producing different bytes than the TEE signed.
|
||||
const raw = Buffer.from(applicantInfoBase64, 'base64');
|
||||
const dataPadded = [...Array.from(raw, b => Number(b)), ...new Array(Math.max(0, KYC_MAX_LENGTH - raw.length)).fill(0)];
|
||||
const dataPadded = [
|
||||
...Array.from(raw, b => Number(b)),
|
||||
...new Array(Math.max(0, KYC_MAX_LENGTH - raw.length)).fill(0),
|
||||
];
|
||||
|
||||
return {
|
||||
data_padded: dataPadded,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "self-workspace-root",
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"app",
|
||||
|
||||
@@ -56,5 +56,8 @@
|
||||
"vite": "^6.1.0",
|
||||
"vitest": "^2.1.8"
|
||||
},
|
||||
"packageManager": "yarn@4.12.0"
|
||||
"packageManager": "yarn@4.12.0",
|
||||
"engines": {
|
||||
"node": ">=22 <23"
|
||||
}
|
||||
}
|
||||
|
||||
10
packages/webview-app/vercel.json
Normal file
10
packages/webview-app/vercel.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "https://openapi.vercel.sh/vercel.json",
|
||||
"buildCommand": "yarn workspace @selfxyz/common build && yarn workspace @selfxyz/mobile-sdk-alpha build:ts-only && yarn workspace @selfxyz/webview-bridge build && yarn workspace @selfxyz/webview-app run build",
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/(.*)",
|
||||
"destination": "/index.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
base: '/',
|
||||
plugins: [
|
||||
react(),
|
||||
{
|
||||
|
||||
@@ -7,6 +7,12 @@ const { spawnSync } = require('child_process');
|
||||
const repositoryRootPath = path.resolve(__dirname, '..');
|
||||
const patchesDirectoryPath = path.join(repositoryRootPath, 'patches');
|
||||
|
||||
// Skip entirely on Vercel — all patches target React Native packages, none apply to web builds
|
||||
if (process.env.VERCEL === '1') {
|
||||
console.log('patch-package: skipping on Vercel (patches are React Native only)');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Detect CI environment
|
||||
const isCI = process.env.CI === 'true' ||
|
||||
process.env.GITHUB_ACTIONS === 'true' ||
|
||||
|
||||
@@ -52,6 +52,7 @@ Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
The SDK Distribution workstream ([SDK Distribution Spec](../sdk-distribution/SPEC.md)) supersedes the CDN bundle approach with hosted URL loading. Native shells will load `https://verify.self.xyz/v1/` directly instead of downloading and verifying CDN bundles.
|
||||
|
||||
With hosted URL loading:
|
||||
|
||||
- Runtime bundle integrity verification is no longer needed — the browser handles HTTPS/TLS verification
|
||||
- The `validateWebViewBundle` Gradle task will be removed as part of SD-01
|
||||
- The build script (`build-webview-bundle.sh`) remains useful for **local development only** — developers can bundle locally and use `devServerUrl` for offline work
|
||||
|
||||
@@ -38,31 +38,31 @@
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Depends On | Type | Status | Notes |
|
||||
| -------------------------------- | ---------- | ------ | ------------------------------------------------------- |
|
||||
| Native Shells (Lite) — NSL-01 | Upstream | Active | Android shell must exist before switching URL loading |
|
||||
| Native Shells (Lite) — NSL-02 | Upstream | Active | iOS shell must exist before switching URL loading |
|
||||
| `packages/webview-app/` | Upstream | Active | Source of the hosted web app |
|
||||
| Build Pipeline | Sibling | Active | Bundle script remains for local dev only after SD-03 |
|
||||
| Depends On | Type | Status | Notes |
|
||||
| ----------------------------- | -------- | ------ | ----------------------------------------------------- |
|
||||
| Native Shells (Lite) — NSL-01 | Upstream | Active | Android shell must exist before switching URL loading |
|
||||
| Native Shells (Lite) — NSL-02 | Upstream | Active | iOS shell must exist before switching URL loading |
|
||||
| `packages/webview-app/` | Upstream | Active | Source of the hosted web app |
|
||||
| Build Pipeline | Sibling | Active | Bundle script remains for local dev only after SD-03 |
|
||||
|
||||
## Ownership Boundaries
|
||||
|
||||
| Area | Owner | Notes |
|
||||
| -------------------------------- | ---------------- | --------------------------------------------- |
|
||||
| `packages/native-shell-android/` | SDK Distribution | Config + URL loading changes only |
|
||||
| `packages/native-shell-ios/` | SDK Distribution | Config + URL loading changes only |
|
||||
| `packages/webview-app/` | SDK Distribution | Hosting setup only (no source changes) |
|
||||
| Bridge handlers | Native Shells | Not modified by this workstream |
|
||||
| Area | Owner | Notes |
|
||||
| -------------------------------- | ---------------- | -------------------------------------- |
|
||||
| `packages/native-shell-android/` | SDK Distribution | Config + URL loading changes only |
|
||||
| `packages/native-shell-ios/` | SDK Distribution | Config + URL loading changes only |
|
||||
| `packages/webview-app/` | SDK Distribution | Hosting setup only (no source changes) |
|
||||
| Bridge handlers | Native Shells | Not modified by this workstream |
|
||||
|
||||
## Backlog
|
||||
|
||||
| ID | Title | Status | Priority | Depends On | Plan | PR |
|
||||
| ----- | ------------------------------ | ------ | -------- | ---------- | ---------------------------------------------------------------------------- | --- |
|
||||
| SD-01 | Android hosted URL loading | Ready | High | NSL-01 | [plans/SD-01-android-hosted-url.md](./plans/SD-01-android-hosted-url.md) | — |
|
||||
| SD-02 | iOS hosted URL loading | Ready | High | NSL-02 | [plans/SD-02-ios-hosted-url.md](./plans/SD-02-ios-hosted-url.md) | — |
|
||||
| SD-03 | WebView app hosting setup | Ready | High | — | [plans/SD-03-hosting-setup.md](./plans/SD-03-hosting-setup.md) | — |
|
||||
| SD-04 | Android Maven publishing | Ready | Medium | SD-01 | [plans/SD-04-android-maven-publishing.md](./plans/SD-04-android-maven-publishing.md) | — |
|
||||
| SD-05 | iOS publishing (SPM + CocoaPods) | Ready | Medium | SD-02 | [plans/SD-05-ios-spm-publishing.md](./plans/SD-05-ios-spm-publishing.md) | — |
|
||||
| ID | Title | Status | Priority | Depends On | Plan | PR |
|
||||
| ----- | -------------------------------- | ------ | -------- | ---------- | ------------------------------------------------------------------------------------ | --- |
|
||||
| SD-01 | Android hosted URL loading | Ready | High | NSL-01 | [plans/SD-01-android-hosted-url.md](./plans/SD-01-android-hosted-url.md) | — |
|
||||
| SD-02 | iOS hosted URL loading | Ready | High | NSL-02 | [plans/SD-02-ios-hosted-url.md](./plans/SD-02-ios-hosted-url.md) | — |
|
||||
| SD-03 | WebView app hosting setup | Ready | High | — | [plans/SD-03-hosting-setup.md](./plans/SD-03-hosting-setup.md) | — |
|
||||
| SD-04 | Android Maven publishing | Ready | Medium | SD-01 | [plans/SD-04-android-maven-publishing.md](./plans/SD-04-android-maven-publishing.md) | — |
|
||||
| SD-05 | iOS publishing (SPM + CocoaPods) | Ready | Medium | SD-02 | [plans/SD-05-ios-spm-publishing.md](./plans/SD-05-ios-spm-publishing.md) | — |
|
||||
|
||||
Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
|
||||
@@ -74,13 +74,13 @@ Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
|
||||
## Active Plans
|
||||
|
||||
| Plan | IDs | Status |
|
||||
| ---------------------------------------------------------------------------- | ----- | ------ |
|
||||
| [plans/SD-01-android-hosted-url.md](./plans/SD-01-android-hosted-url.md) | SD-01 | Ready |
|
||||
| [plans/SD-02-ios-hosted-url.md](./plans/SD-02-ios-hosted-url.md) | SD-02 | Ready |
|
||||
| [plans/SD-03-hosting-setup.md](./plans/SD-03-hosting-setup.md) | SD-03 | Ready |
|
||||
| Plan | IDs | Status |
|
||||
| ------------------------------------------------------------------------------------ | ----- | ------ |
|
||||
| [plans/SD-01-android-hosted-url.md](./plans/SD-01-android-hosted-url.md) | SD-01 | Ready |
|
||||
| [plans/SD-02-ios-hosted-url.md](./plans/SD-02-ios-hosted-url.md) | SD-02 | Ready |
|
||||
| [plans/SD-03-hosting-setup.md](./plans/SD-03-hosting-setup.md) | SD-03 | Ready |
|
||||
| [plans/SD-04-android-maven-publishing.md](./plans/SD-04-android-maven-publishing.md) | SD-04 | Ready |
|
||||
| [plans/SD-05-ios-spm-publishing.md](./plans/SD-05-ios-spm-publishing.md) | SD-05 | Ready |
|
||||
| [plans/SD-05-ios-spm-publishing.md](./plans/SD-05-ios-spm-publishing.md) | SD-05 | Ready |
|
||||
|
||||
## Completion Checklist
|
||||
|
||||
@@ -91,20 +91,20 @@ Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
| Decision | Choice | Rationale |
|
||||
| -------------------- | --------------------------------------- | --------------------------------------------------------------- |
|
||||
| Hosting domain | `https://verify.self.xyz/v1/` | User-facing, version-namespaced, HTTPS-only |
|
||||
| Versioning model | Auto-update (hosted page updates independently) | `/v1/` path changes only for breaking changes to bridge protocol |
|
||||
| Config delivery | `webAppUrl` field with default | Simple, overridable, does not leak config into query params |
|
||||
| Hosting | Internal infrastructure | SD-03 describes requirements only |
|
||||
| Bundle script fate | Retained for local dev | Developers need `devServerUrl` alternative for offline work |
|
||||
| Decision | Choice | Rationale |
|
||||
| ------------------ | ----------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| Hosting domain | `https://verify.self.xyz/v1/` | User-facing, version-namespaced, HTTPS-only |
|
||||
| Versioning model | Auto-update (hosted page updates independently) | `/v1/` path changes only for breaking changes to bridge protocol |
|
||||
| Config delivery | `webAppUrl` field with default | Simple, overridable, does not leak config into query params |
|
||||
| Hosting | Internal infrastructure | SD-03 describes requirements only |
|
||||
| Bundle script fate | Retained for local dev | Developers need `devServerUrl` alternative for offline work |
|
||||
|
||||
## Related Specs
|
||||
|
||||
| Spec | Relationship |
|
||||
| ---------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| [SDK Overview](../../OVERVIEW.md) | Parent architecture |
|
||||
| [Native Shells Lite](../native-shells-lite/SPEC.md) | Upstream — shells must exist before distribution changes |
|
||||
| [Build Pipeline](../build-pipeline/SPEC.md) | Sibling — bundle script retained for local dev only |
|
||||
| [WebView Spec](../webview/SPEC.md) | Upstream — produces the web app being hosted |
|
||||
| [SDK Core Spec](../sdk-core/SPEC.md) | Sibling — engine consumed by hosted web app |
|
||||
| Spec | Relationship |
|
||||
| --------------------------------------------------- | -------------------------------------------------------- |
|
||||
| [SDK Overview](../../OVERVIEW.md) | Parent architecture |
|
||||
| [Native Shells Lite](../native-shells-lite/SPEC.md) | Upstream — shells must exist before distribution changes |
|
||||
| [Build Pipeline](../build-pipeline/SPEC.md) | Sibling — bundle script retained for local dev only |
|
||||
| [WebView Spec](../webview/SPEC.md) | Upstream — produces the web app being hosted |
|
||||
| [SDK Core Spec](../sdk-core/SPEC.md) | Sibling — engine consumed by hosted web app |
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
### Implementation Details
|
||||
|
||||
1. **Add `maven-publish` plugin**:
|
||||
|
||||
```kotlin
|
||||
plugins {
|
||||
// existing plugins...
|
||||
@@ -55,6 +56,7 @@
|
||||
```
|
||||
|
||||
2. **Configure publication**:
|
||||
|
||||
```kotlin
|
||||
afterEvaluate {
|
||||
publishing {
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
- No committed build artifacts in the package directory
|
||||
|
||||
3. **Add `SelfSDK.podspec`**:
|
||||
|
||||
```ruby
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'SelfSDK'
|
||||
@@ -76,6 +77,7 @@
|
||||
s.source_files = 'packages/native-shell-ios/Sources/**/*.swift'
|
||||
end
|
||||
```
|
||||
|
||||
Adjust `source`, `source_files`, and module name to match the actual repo structure and naming.
|
||||
|
||||
4. **Tag and test SPM consumption**:
|
||||
|
||||
@@ -67,23 +67,23 @@ webview backlog.
|
||||
|
||||
## Backlog
|
||||
|
||||
| ID | Title | Status | Priority | Depends On | Plan | Notes |
|
||||
| ----- | ----------------------------------------------------------------------------------------------- | ----------- | -------- | ------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| WV-01 | Dynamic proof request items sourced from request context | Done | High | - | [plans/WV-01-dynamic-proof-request-items.md](./plans/WV-01-dynamic-proof-request-items.md) | Existing active follow-up |
|
||||
| WV-02 | Define the KYC-provider contract for document capture, MRZ/liveness handoff, and result mapping | Done | High | - | [plans/WV-02-kyc-provider-contract.md](./plans/WV-02-kyc-provider-contract.md) | Provider-backed path replaces Self-owned native scan flow; active contract is now documented |
|
||||
| WV-03 | Remove native NFC and native-scan assumptions from active WebView screens, copy, and docs | Done | High | WV-02 | [plans/WV-03-remove-native-scan-assumptions.md](./plans/WV-03-remove-native-scan-assumptions.md) | Active UX/docs now route to a provider placeholder instead of Self-managed scan screens |
|
||||
| WV-04 | Define the host callback contract for launch, dismiss, and final result without native modules | Done | Medium | WV-02 | [plans/WV-04-host-callback-contract.md](./plans/WV-04-host-callback-contract.md) | Browser host fallback now uses `postMessage` for iframe/popup embedding while native transports keep their current behavior |
|
||||
| WV-05 | Integrate KYC provider Web SDK into ProviderLaunchScreen | In Progress | High | WV-02 | [plans/WV-05-kyc-provider-sdk.md](./plans/WV-05-kyc-provider-sdk.md) | **Next phase.** Needs rework for Didit (prior Sumsub branch is stale) |
|
||||
| WV-06 | Wire KYC result through verification pipeline to host lifecycle callback | Ready | High | WV-05 | [plans/WV-06-kyc-result-flow.md](./plans/WV-06-kyc-result-flow.md) | **Next phase.** KYC result → kycResultStore → ConfirmIdentificationScreen → lifecycle.setResult() |
|
||||
| WV-07 | SelfClient assembly and proving machine export for WebView | Done | High | SC-03 | [plans/WV-07-selfclient-proving-assembly.md](./plans/WV-07-selfclient-proving-assembly.md) | Export useProvingStore, map bridge→SDK adapters, keychain-backed documents, create real SelfClient |
|
||||
| WV-08 | Wire tunnel flow with real proving machine (register → disclose) | Ready | High | WV-05, WV-06, WV-07 | [plans/WV-08-tunnel-proving-flow.md](./plans/WV-08-tunnel-proving-flow.md) | **Next phase.** Replace mock tunnel proving with real provingMachine: KYC → store doc → prove → disclose → result |
|
||||
| WV-09 | Registration core (tour, outcomes, mocked provider handoff) | Ready | High | - | [plans/WV-09-registration-core.md](./plans/WV-09-registration-core.md) | Critical path: 7 Euclid wrappers (tour + outcomes) plus mocked provider transitions; minimum viable registration spine |
|
||||
| WV-10 | EU ID defer record | Deferred | Low | - | [plans/WV-10-eu-id-helper-flow.md](./plans/WV-10-eu-id-helper-flow.md) | EU ID is a 3.1 follow-up alongside Aadhaar and Points; not part of the active registration mock-migration pass |
|
||||
| WV-11 | Disclose core | Ready | High | WV-07, WV-08 | [plans/WV-11-disclose-core.md](./plans/WV-11-disclose-core.md) | **Next phase.** Request-context entry → proof request → generation → result |
|
||||
| WV-12 | Registration prompts (social sign-on, conflict, notifications) | Ready | Medium | WV-09 | [plans/WV-12-registration-prompts.md](./plans/WV-12-registration-prompts.md) | 4 Euclid wrappers split from WV-09; not required for minimum registration spine |
|
||||
| WV-13 | Proof overlays, history, and post-proof support | Blocked | Medium | WV-11 | — | Spec needed; receipt, history, dialogues, success/backup prompts, KYC pending/success, Nova splash |
|
||||
| WV-14 | Home, document management, and ID data | Blocked | Medium | WV-11 | — | Spec needed; IDDataScreen, ManageDocumentsScreen, HomeScreen follow-through |
|
||||
| WV-15 | Recovery and backup surfaces | Blocked | Low | WV-14 | — | Spec needed; recovery method picker, phrase display/input, recovery success |
|
||||
| ID | Title | Status | Priority | Depends On | Plan | Notes |
|
||||
| ----- | ----------------------------------------------------------------------------------------------- | ----------- | -------- | ------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| WV-01 | Dynamic proof request items sourced from request context | Done | High | - | [plans/WV-01-dynamic-proof-request-items.md](./plans/WV-01-dynamic-proof-request-items.md) | Existing active follow-up |
|
||||
| WV-02 | Define the KYC-provider contract for document capture, MRZ/liveness handoff, and result mapping | Done | High | - | [plans/WV-02-kyc-provider-contract.md](./plans/WV-02-kyc-provider-contract.md) | Provider-backed path replaces Self-owned native scan flow; active contract is now documented |
|
||||
| WV-03 | Remove native NFC and native-scan assumptions from active WebView screens, copy, and docs | Done | High | WV-02 | [plans/WV-03-remove-native-scan-assumptions.md](./plans/WV-03-remove-native-scan-assumptions.md) | Active UX/docs now route to a provider placeholder instead of Self-managed scan screens |
|
||||
| WV-04 | Define the host callback contract for launch, dismiss, and final result without native modules | Done | Medium | WV-02 | [plans/WV-04-host-callback-contract.md](./plans/WV-04-host-callback-contract.md) | Browser host fallback now uses `postMessage` for iframe/popup embedding while native transports keep their current behavior |
|
||||
| WV-05 | Integrate KYC provider Web SDK into ProviderLaunchScreen | In Progress | High | WV-02 | [plans/WV-05-kyc-provider-sdk.md](./plans/WV-05-kyc-provider-sdk.md) | **Next phase.** Needs rework for Didit (prior Sumsub branch is stale) |
|
||||
| WV-06 | Wire KYC result through verification pipeline to host lifecycle callback | Ready | High | WV-05 | [plans/WV-06-kyc-result-flow.md](./plans/WV-06-kyc-result-flow.md) | **Next phase.** KYC result → kycResultStore → ConfirmIdentificationScreen → lifecycle.setResult() |
|
||||
| WV-07 | SelfClient assembly and proving machine export for WebView | Done | High | SC-03 | [plans/WV-07-selfclient-proving-assembly.md](./plans/WV-07-selfclient-proving-assembly.md) | Export useProvingStore, map bridge→SDK adapters, keychain-backed documents, create real SelfClient |
|
||||
| WV-08 | Wire tunnel flow with real proving machine (register → disclose) | Ready | High | WV-05, WV-06, WV-07 | [plans/WV-08-tunnel-proving-flow.md](./plans/WV-08-tunnel-proving-flow.md) | **Next phase.** Replace mock tunnel proving with real provingMachine: KYC → store doc → prove → disclose → result |
|
||||
| WV-09 | Registration core (tour, outcomes, mocked provider handoff) | Ready | High | - | [plans/WV-09-registration-core.md](./plans/WV-09-registration-core.md) | Critical path: 7 Euclid wrappers (tour + outcomes) plus mocked provider transitions; minimum viable registration spine |
|
||||
| WV-10 | EU ID defer record | Deferred | Low | - | [plans/WV-10-eu-id-helper-flow.md](./plans/WV-10-eu-id-helper-flow.md) | EU ID is a 3.1 follow-up alongside Aadhaar and Points; not part of the active registration mock-migration pass |
|
||||
| WV-11 | Disclose core | Ready | High | WV-07, WV-08 | [plans/WV-11-disclose-core.md](./plans/WV-11-disclose-core.md) | **Next phase.** Request-context entry → proof request → generation → result |
|
||||
| WV-12 | Registration prompts (social sign-on, conflict, notifications) | Ready | Medium | WV-09 | [plans/WV-12-registration-prompts.md](./plans/WV-12-registration-prompts.md) | 4 Euclid wrappers split from WV-09; not required for minimum registration spine |
|
||||
| WV-13 | Proof overlays, history, and post-proof support | Blocked | Medium | WV-11 | — | Spec needed; receipt, history, dialogues, success/backup prompts, KYC pending/success, Nova splash |
|
||||
| WV-14 | Home, document management, and ID data | Blocked | Medium | WV-11 | — | Spec needed; IDDataScreen, ManageDocumentsScreen, HomeScreen follow-through |
|
||||
| WV-15 | Recovery and backup surfaces | Blocked | Low | WV-14 | — | Spec needed; recovery method picker, phrase display/input, recovery success |
|
||||
| WV-16 | Settings follow-through and support routes | Done | Low | WV-14 | — | Delivered: haptic wiring on all menu items, dev-mode mock generation fixed, Manage Documents description fixed, DevRouteMenu Settings + Tunnel groups added, settings screen tests. Deferred: notification toggle and backup-enabled persistence (requires storage design decision, not blocking UI completeness) |
|
||||
|
||||
Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
|
||||
Reference in New Issue
Block a user