Commit Graph
42 Commits
Author SHA1 Message Date
Sergey KozyrenkoandClaude Opus 4.8 2d2aea5785 fix(auth): reject OAuth logins with a provider-unverified email
The OAuth callback links/creates an account by the email from ResolveEmail, and
Google/GitHub only ever return a verified address — but that invariant lived
inside each provider and was invisible at the callback. A future OAuth provider
that omitted the verified check would let an attacker register a victim's email
there (unverified), "sign in", and be linked straight into the victim's account:
instant takeover.

Make verification part of the contract: ResolveEmail now returns
(email, verified, err), and the callback refuses to proceed when !verified.
Because Go's bool zero value is false and the compiler forces the new return, a
provider that forgets to report verification fails closed (its own login breaks)
rather than opening a takeover. Google reports claims.EmailVerified; GitHub only
selects verified addresses, so reports true. Added a callback test: a provider
reporting an unverified email is rejected (no link, no session) — red before the
gate, green after.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 14:43:16 +07:00
Sergey KozyrenkoandClaude Opus 4.8 497cfdd555 fix(users): require a real email on user-initiated email change
EmailChange.Mail validated with `vmail`, which accepts not just a real address
but also the literal "admin" and any UUID — escape hatches that exist so the
seeded admin row (mail "admin") passes User.Mail's Valid(). The account's
change-email form (added this branch) reaches it, so a user could save "admin"
or a UUID as their own email — a non-deliverable value (no privilege gain: roles
come from role_id, and UNIQUE(mail) blocks colliding with the real admin row).

Add a strict `realemail` validator (same address regex as vmail, minus the
hatches) and use it for EmailChange.Mail; User.Mail keeps `vmail` so the seeded
admin still validates. Tests cover the validator (admin/UUID rejected, real
address accepted) and the handler (changing to a UUID or "admin" now 400s).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 13:00:36 +07:00
Sergey KozyrenkoandClaude Opus 4.8 14e0a0ae71 fix(users): preserve email case on change to match login, OAuth and create
ChangeEmailCurrentUser was the only path that lowercased the email
(strings.ToLower), while local login, the OAuth callback and CreateUser all
store/compare it raw against a case-sensitive UNIQUE(mail). That lone
normalization let a changed address (now lowercased) miss a later raw-case
login, and let the uniqueness pre-check (run on the lowercased value) skip an
existing mixed-case row. Drop the ToLower so every path is consistently
case-sensitive again — the pre-branch invariant. The email validator already
rejects surrounding whitespace, so the paired TrimSpace was dead.

Update the test that codified the old lowercasing to assert case preservation.
A fully case-insensitive scheme (normalize everywhere, or citext /
UNIQUE(lower(mail))) is tracked separately as a follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 10:15:44 +07:00
Sergey KozyrenkoandClaude Opus 4.8 28036f652c refactor(providers): table-driven provider registry
The provider controller repeated every provider type across five hand-written
blocks (default-config wiring, key-gated instantiation, GetProvider fallback,
NewProvider, buildProviderFromConfig) plus the API-layer Valid() whitelist.

Introduce pkg/providers/registry.go: a providerRegistry table whose entries hold
the per-type constructors and credential gating, with small adapter helpers
(ignoreConfig/fromData) absorbing the signature variance (bedrock/ollama/custom
take *config.Config; the rest don't). The controller now wires and looks up
providers in loops over the table. Valid() validates against the new canonical
provider.AllProviderTypes list (no heavyweight import, no cycle).

Adding a provider's backend wiring drops from ~6 edits across these functions to
one registry entry. providers.go shrinks ~300 lines; behavior is unchanged
(same exported funcs, same gating) and all provider/server/graph tests stay green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 19:07:11 +07:00
Sergey KozyrenkoandClaude Opus 4.8 bfd80b1de9 test(minimax): cover provider whitelist + secret pattern parity (refs #328)
The QA audit found minimax was wired into production everywhere but omitted
from provider-enumeration test data, so a future regression dropping it would
go uncaught. Add minimax to ProviderType.Valid()'s validTypes table, to the
GetSecretPatterns config (expected count 29→30, exercising the "MiniMax Key"
redaction pattern), and to clearConfigEnv's hermetic env list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 16:25:51 +07:00
Sergey KozyrenkoandClaude Opus 4.8 55335feb17 feat(minimax): add MiniMax provider with full app/UI/installer parity (refs #328)
Reworks external PR #328 (octo-patch). The PR added only the provider core;
this brings MiniMax to full parity with the other providers (qwen) so it is
selectable and configurable in the UI and installer.

Applied from the PR (verified against MiniMax's official API docs — M3/M2.7/
M2.7-highspeed are real current models; corrected the M3 description from the
PR's "512K" to the documented ~1M context):
- minimax provider package (OpenAI-compatible https://api.minimax.io/v1),
  config.yml, models.yml, tests; MINIMAX_API_KEY/SERVER_URL/PROVIDER env vars;
  ProviderMiniMax type + DefaultProviderNameMiniMax; providers.go wiring;
  Valid() whitelist.

Added for completeness:
- goose migration adding 'minimax' to the PROVIDER_TYPE enum + database
  ProviderTypeMinimax const.
- GraphQL: minimax in ProviderType enum, ProvidersModelsList,
  ProvidersReadinessStatus, DefaultProvidersConfig; resolvers wire default
  config/models + enabled status; gqlgen regenerated.
- Frontend: MiniMax icon (lobehub), provider-icon + settings-providers
  registration + provider type list; regenerated GraphQL types.
- Installer wizard: provider form, screen, list, registry, env-var mappings,
  locale strings + help text.
- ctester/ftester: -type/-provider minimax support.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 15:24:04 +07:00
mason5052 3c6bea3c5d fix: return structured error when zip build fails before streaming
Commit the ZIP response status and headers lazily, on the first byte written, via a small zipStreamWriter. A build failure before any output now returns the normal structured error response instead of a committed 200 with a truncated body; mid-stream failures still abort. Also check the reader Close error in the helper test and cover the pre-stream failure path.
2026-06-19 04:20:28 +07:00
mason5052 f7e2ac6615 fix: stream zip downloads without buffering archive
DownloadResource and DownloadFlowFile built the entire ZIP archive in a bytes.Buffer before sending it, so heap usage scaled with archive size and a few concurrent large-directory downloads could exhaust process memory.

Stream the archive straight to the response writer via a shared streamZipArchive helper; the existing ZipResources/ZipDirectory/ZipRelativePaths helpers already accept an io.Writer. Responses are now chunked (no Content-Length) and memory stays proportional to one file's copy buffer.
2026-06-19 04:20:28 +07:00
Sergey KozyrenkoandClaude Fable 5 9a5a8b53a5 fix(server): return 404 from name change when the user no longer exists
ChangeNameCurrentUser issued a bare UPDATE and ignored RowsAffected, so a stale
session for a deleted user got 200 — inconsistent with the email/password handlers
(which 404) and leaving the frontend's Users.NotFound mapping unreachable.

- check RowsAffected and return ErrUsersNotFound (404) when no row matched
- document the 404 in the swagger annotation
- add TestChangeNameCurrentUser (success, missing user, invalid name)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-14 10:35:52 +07:00
Sergey KozyrenkoandClaude Fable 5 c14ba936fb fix(auth): accept mixed-case and long-TLD emails; normalize on change
The vmail validator rejected addresses the frontend's z.string().email() accepts
(uppercase, TLDs longer than 4 chars like .cloud), so users saw a confusing 400.

- relax the vmail regex to allow uppercase and TLDs of 2+ chars
- lowercase + trim the new address in ChangeEmailCurrentUser and in the form schema
  so storage, the duplicate check, and login lookups stay case-stable
- validator + change-email tests for mixed case and long TLDs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 19:26:44 +07:00
Sergey KozyrenkoandClaude Fable 5 06178bf868 fix(server): link OAuth logins to existing accounts by email; harden email change
- authLoginCallback matches users by email alone so an OAuth login links into an
  existing (incl. local) account instead of 500-ing on users_mail_unique
- relink on a create-branch unique-violation race instead of returning 500
- issue the session with the linked account's actual role privileges
- clear the stale OAuth provider link when a user changes their email
- map the email-change unique-violation race to 409 instead of 500
- isUniqueViolation matches Postgres and SQLite case-insensitively
- tests for link/create/blocked/role-inheritance/race, email 409, provider reset
- update auth form test selectors after the form refactor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 19:00:26 +07:00
Sergey KozyrenkoandClaude Opus 4.8 7d504914b8 feat(server): persist OAuth provider and add self-service name change
- OAuth login callback now stores the provider (google/github) on the
  user record and backfills it for pre-existing OAuth users on login,
  so the UI can show which provider an account is linked to.
- Add PUT /user/name for any authenticated user (including OAuth): a
  NameChange model + ChangeNameCurrentUser handler that lets users edit
  their display name. Placed in a /user group without localUserRequired.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 02:56:15 +07:00
Sergey Kozyrenko 182642ba6b Merge pull request #340 from Akalanka1337/user-profile-email-update
Replace Change Password with My Profile (email and password update)
2026-06-11 19:35:53 +07:00
Sergey KozyrenkoandClaude Fable 5 99c8b6786c fix: recover from stale-chunk and DOM-desync SPA crashes
Two crashes seen in production, both reproduced on the live app:

- "Failed to fetch dynamically imported module": after a redeploy rotates the
  hashed chunk filenames, an open tab imports a deleted one. The server answered a
  missing /assets/* with 301 -> index.html (HTML for a JS module -> a MIME
  failure); it now returns 404 + no-store. The client listens for Vite's
  vite:preloadError and reloads once (debounced) to pull the current build. Hashed
  assets are served immutable; index.html and SPA routes no-cache.

- "Failed to execute 'removeChild' ... not a child of this node": an external
  agent (a browser extension or auto-translation) mutates the DOM React owns,
  desyncing reconciliation. A root react-router errorElement catches this
  commit-phase crash and self-heals with a debounced reload, instead of React
  Router's dead default error screen. translate="no" opts the English-only UI out
  of the one trigger it can prevent (browser translation); the errorElement covers
  the rest regardless of source.

Verified by reproducing both on the live old build (missing-chunk 301->HTML;
extension/translation DOM mutation -> the exact removeChild crash) and confirming
the fixed build recovers from each. Adds chunk-reload + RouteErrorBoundary unit
tests and a static-serving integration test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:32:34 +07:00
Akalanka1337 82bca05ac3 feat(webui): replace Change Password with My Profile (email and password updates) 2026-06-05 23:51:36 +05:30
Dmitry Ng 39f122467d feat(config): add new embedding and rename database connection pool settings
- Introduced `EMBEDDING_MAX_TEXT_BYTES` to limit the maximum byte size of text sent to the embedding model.
- Renamed database connection pool settings: `DATABASE_MAX_OPEN_CONNS`, `DATABASE_MAX_IDLE_CONNS`, and `DATABASE_VECTOR_MAX_CONNS` for improved PostgreSQL connection management.
- Updated relevant documentation to reflect these new configuration options and their usage.
- Adjusted various components to utilize the new settings for enhanced performance and resource management.
2026-05-18 18:26:52 +03:00
Dmitry Ng 2ce863ec1a feat(toolcall): implement ToolCall logging functionality
- Added ToolCallLogProvider interface with methods for logging tool calls, updating success and failure statuses.
- Introduced proxyToolCallLogProvider to handle ToolCall logging operations.
- Updated flow execution components to integrate ToolCall logging, including flow workers and controllers.
- Enhanced GraphQL schema to support ToolCall logs, including queries and subscriptions for real-time updates.
- Updated documentation to reflect the new ToolCall logging features and their usage.
2026-05-18 11:21:56 +03:00
Dmitry Ng 077ddce476 feat(database): enhance PostgreSQL connection pooling and configuration
- Introduced shared connection pooling for PostgreSQL using `*sql.DB` for sqlc and GORM, optimizing resource usage.
- Added new environment variables: `DB_MAX_OPEN_CONNS`, `DB_MAX_IDLE_CONNS`, and `DB_VECTOR_MAX_CONNS` for configurable connection limits.
- Updated documentation to reflect new connection pooling strategy and provide operational commands for monitoring.
- Implemented shared `pgxpool` for pgvector stores to reduce connection overhead and improve performance.
- Adjusted various components to utilize the new connection pooling setup, ensuring efficient database interactions.
2026-05-18 11:13:43 +03:00
Dmitry Ng 403a84b0a6 feat(toolcalls): implement toolcall management features via REST API
- Added a new SQL migration to insert toolcall privileges into the privileges table.
- Introduced the `ToolcallService` for managing toolcall data, including retrieval of toolcalls and flow-specific toolcalls.
- Implemented API endpoints for fetching toolcalls and toolcall details, with appropriate permission checks.
- Enhanced Swagger documentation to include new toolcall endpoints and their specifications.
- Created a new model for toolcalls, defining their structure and validation rules.
- Added error handling for invalid toolcall requests and not found scenarios.
2026-05-14 14:12:37 +03:00
Dmitry Ng 2f4da118e0 feat(anonymization): implement anonymizeText mutation and associated service
- Added a new SQL migration to insert the 'anonymize.call' privilege into the privileges table.
- Introduced the `anonymizeText` mutation in the GraphQL schema, allowing users to anonymize sensitive text.
- Implemented the `AnonymizerService` to handle text anonymization requests via a REST API endpoint.
- Updated the GraphQL resolver to integrate the new mutation and ensure proper permission checks.
- Enhanced documentation with Swagger and OpenAPI specifications for the new endpoint.
- Added error handling for invalid requests and unavailable anonymizer configurations.
2026-05-12 21:47:40 +03:00
Dmitry Ng ba0cee43c8 fix(router): add new frontend routes for resources and knowledges to preserve route in the browser
- Introduced "/resources" and "/knowledges" routes to the frontendRoutes array in the router configuration, expanding the application's routing capabilities.
2026-05-08 20:46:47 +03:00
Dmitry Ng a9aeb81e4e refactor(resources): update MoveResourceRequest to allow empty destination
- Removed the requirement for the "destination" field in MoveResourceRequest, allowing it to be an empty string, which signifies moving to the root directory.
- Updated related documentation in swagger.json, swagger.yaml, and docs.go to reflect the new behavior.
- Adjusted the MoveResource function to handle cases where the destination is empty, ensuring proper path sanitization and resource movement semantics.
- Enhanced test cases to cover scenarios involving moving resources to the root directory and handling conflicts appropriately.
2026-05-08 20:24:39 +03:00
Dmitry Ng dc2fd43928 feat(assistants): support flowID=0 in REST API to create assistant with new flow
- Allow POST /flows/0/assistants/ to create a new flow together with the assistant, mirroring the existing GraphQL createAssistant(flowID: 0) behavior
- Require both assistants.create and flows.create permissions when flowID=0
- Add explicit flow ownership check for non-zero flowID using flows.admin scope
- Load flow data in the response by fetching it via assistant.FlowID after creation, ensuring AssistantFlow is fully populated in all cases
2026-05-08 18:54:14 +03:00
Dmitry Ng a348e41a31 feat(settings): add version and isDevelopMode fields to Settings model and GraphQL schema
- Introduced new fields `version` and `isDevelopMode` in the Settings model to provide application versioning and development mode status.
- Updated GraphQL schema and resolvers to support the new fields, ensuring they are accessible via the Settings query.
- Enhanced Swagger documentation to reflect the changes in the Settings API endpoint.
- Added necessary validation and response handling for the new fields in the Settings service.
2026-05-08 13:06:07 +03:00
Dmitry Ng 6890584c64 feat(resources): add multi-source move, copy and flow-file promotion
- Add Sources []string to MoveResourceRequest, CopyResourceRequest and AddResourceFromFlowRequest; merged with Source, deduplicated; multi-source uses destination as base dir and runs in a single atomic DB transaction
- Fix MoveResource response to return Added + Updated (not Updated only) so Apollo cache receives new parent directory entries alongside moved items
- Add missing errResourceNotFound case in CopyResource (was 500 instead of 404)
- Cover all new behaviour with table-driven tests (basename conflict, force overwrite, missing source, empty input, dir-into-itself guard, etc.)
2026-05-06 17:03:13 +03:00
Dmitry Ng 3a52079278 feat(knowledge): add pgvector knowledge base management
- GraphQL/REST CRUD + semantic search for knowledge documents
- KnowledgeStore with admin/user-scoped filtering, re-embedding on update
- Real-time subscriptions (created/updated/deleted) per user and admin
- user_id tracking in all agent-stored documents (guide/answer/code/memory)
- sqlc queries, goose migrations, privilege grants, user_id backfill
- Memory cleanup on flow deletion; stale orphan purge via migration
- Unit tests for all KnowledgeStore operations including security cases
- Frontend GraphQL schema and TypeScript types regenerated
2026-05-05 01:09:20 +03:00
Dmitry Ng ca9f4a0211 feat: add multi-path support and ZIP improvements across file APIs
- Added `paths[]` query/body parameter to DeleteFlowFile, DownloadFlowFile,
  GetFlowContainerFiles, PullFlowFiles, ListResources, DeleteResource, and
  DownloadResource; single `path` parameter retained for backward compatibility.
- Introduced `DeduplicatePaths` in flowfiles package with coverage-based
  deduplication (parent covers children), path normalization, and traversal safety.
- Added `ZipRelativePaths` to create ZIP archives from cache-relative paths,
  sharing `zipWriteFile` helper with refactored `ZipDirectory`.
- Switched all ZIP and single-file responses to buffered `DataFromReader` with
  explicit `Content-Length`, fixing Swagger UI download rendering.
- Expanded response payloads: delete and pull operations now enumerate all
  affected nested files; list responses include ancestor directories for tree
  completeness.
- Extended test coverage across flowfiles, flow_files, and resources packages
  with batch, deduplication, atomicity, Docker exec, and security scenarios.
2026-05-04 14:32:39 +03:00
Dmitry Ng 8830ae7010 fix: update resource handling and API documentation
- Adjusted descriptions in API documentation to clarify paths for uploads, resources, and containers.
- Updated data models to use consistent naming conventions (e.g., `isDir` to `is_dir`, `modifiedAt` to `modified_at`).
- Changed resource ID types from string to uint64 for better consistency across the application.
- Enhanced flow file upload functionality to support batch processing of resource files.
- Removed deprecated code related to resource entry responses in tests.
2026-05-01 16:11:09 +03:00
Dmitry Ng 1d6f842bb9 test: add comprehensive coverage for FlowFileService HTTP handlers
- Added table-driven scenarios for all 8 endpoints (Get/Upload/Delete/Download flow files, Pull from container, GetContainerFiles, AddResourcesToFlow, AddResourceFromFlow) covering success paths, all privilege combinations (view/upload/admin/cross-user), error responses (forbidden/not-found/conflict/invalid request), and security checks (path traversal, symlink rejection).
- Introduced reusable test infrastructure: sqlite-backed flows/user_resources schema, fakeDockerClient implementing the full docker.DockerClient interface, flowFileCaptureSubscriptions recording both FlowPublisher and ResourcePublisher events, and helpers for multipart upload bodies and container TAR fixtures.
- Added direct unit tests for shellQuote, parseFlowIDParam, cleanupPendingUploads, and flowScopeForFiles privilege matrix.
- Lifts handler coverage from 0% to 60-90% across the file and total services package coverage from 10.2% to 28.6%.
2026-04-28 22:48:23 +03:00
Dmitry Ng 452a2d51e2 fix: expand ResourceService coverage with comprehensive scenarios
- Restructured single-case tests for List, Mkdir, Download, and CleanupOrphanBlobs into table-driven scenarios.
- Extended Upload, Delete, Copy, and Move scenarios with admin, forbidden, malformed JSON, invalid path, missing source, and trailing-slash hint cases.
- Added dedicated tests for blob deduplication on upload/copy, non-multipart bodies, orphan blob preservation on rollback, and direct deleteOrphanBlob coverage.
- Introduced helpers for parameterized multipart field names, custom UID context, and on-disk blob counting.
2026-04-28 22:02:49 +03:00
Dmitry Ng aa4b70eaba feat: add user resources system and flow integration
- UserResource model with MD5-deduplicated blob storage and virtual path filesystem
- REST API for resource CRUD (upload, mkdir, move, copy, delete, download)
- GraphQL query/mutations with resourceIds support on createFlow, putUserInput, createAssistant, callAssistant
- Resource → flow copy with hierarchy restore; incremental container sync (find missing, copy once)
- FlowWorker.PutResources delegates copy, docker push and flowFileAdded events
- Agent prompts updated with {{.UserFiles}} XML listing of /work/uploads and /work/resources
- Resource subscriptions: resourceAdded/Updated/Deleted
2026-04-28 17:00:17 +03:00
Dmitry Ng 7c4ebda2c2 feat: enhance Docker client with container file operations and API integration
- Added methods for non-recursive directory listing and file stat operations in the Docker client.
- Implemented a new API endpoint to retrieve files from a running container's directory.
- Updated documentation to reflect new file operations and API changes.
- Introduced data structures for container file metadata and integrated them into the flow file service.
- Enhanced flow file management capabilities with improved synchronization between local and container file systems.
2026-04-27 13:19:39 +03:00
Dmitry Ng 72b1c8489e feat: implement flow file management with upload and retrieval capabilities
- Added new endpoints for managing flow files, including listing, uploading, and deleting files within flow workspaces.
- Introduced FlowFile model to represent file metadata.
- Enhanced GraphQL schema to support flow file operations and subscriptions for real-time updates.
- Updated API documentation to reflect new flow file functionalities.
2026-04-27 10:03:42 +03:00
mason5052 263eaf56ab fix: harden flow file uploads
Signed-off-by: mason5052 <ehehwnwjs5052@gmail.com>
2026-04-22 12:35:55 -04:00
mason5052 4d7c3678a9 feat: add flow-scoped file uploads 2026-04-19 14:27:06 -04:00
Dmitry Ng 7c25f356ed feat: enable runtime provider switching
Adds conditional chain normalization in processChain to preserve reasoning cache when provider unchanged while fixing incomplete tool_calls and converting IDs when switching providers. Extends GraphQL API with modelProvider parameter for seamless provider changes without restart.
2026-04-08 23:58:56 +03:00
Dmitry Ng fc91758b9c Merge pull request #238 from vxcontrol/feature/frontend
Add Analytics Dashboard and Template Management System
2026-04-08 04:36:05 +04:00
Dmitry Ng 089dcb36b4 feat: implement flow templates management 2026-04-08 03:34:32 +03:00
mason5052 1b2681cd99 test: shadow loop variable to prevent parallel subtest capture
Add tt := tt inside each for-range loop before t.Run to ensure
parallel subtests capture their own immutable copy of the test case.
2026-04-06 19:15:29 -04:00
mason5052 62dbefdd25 test: fill coverage gaps in server/models validation tests
Add missing test coverage identified by cross-review:

New files:
- assistants_test.go: AssistantStatus enum, Assistant struct, CreateAssistant,
  PatchAssistant (stop/input actions), AssistantFlow nested validation
- prompts_test.go: PromptType enum (8 valid constants from templates pkg),
  Prompt struct, PatchPrompt validation

Extended existing files:
- users_test.go: add AuthCallback positive-path test, UserRolePrivileges
  validation, fix brittle double-call assertion in UserPreferences test
- api_tokens_test.go: add APITokenWithSecret validation (valid, invalid
  embedded token, invalid JWT)
- flows_test.go: add Flow.Valid, FlowTasksSubtasks.Valid,
  FlowContainers.Valid, Task.Valid, TaskSubtasks.Valid, Subtask.Valid,
  Container.Valid with valid/invalid/missing-field cases
2026-03-31 21:53:39 -04:00
mason5052 5d4638e79d test: add unit tests for server/models validation functions
Add comprehensive test coverage for the server/models package validation
logic including enum types, struct validators, and custom validators.

Test files added:
- users_test.go: UserStatus, UserType, Login, Password, User,
  UserPassword, AuthCallback, UserRole, UserPreferences validation
- providers_test.go: ProviderType, Provider, CreateProvider,
  PatchProvider, ProviderInfo validation
- api_tokens_test.go: TokenStatus, APIToken, CreateAPITokenRequest,
  UpdateAPITokenRequest, APITokenClaims validation
- flows_test.go: FlowStatus, TaskStatus, SubtaskStatus, ContainerStatus,
  ContainerType, Role, Privilege, RolePrivileges, PatchFlow validation
- init_test.go: Custom validators (stpass, vmail, oauth_min_scope,
  solid, semver, semverex) and scanFromJSON helper
2026-03-31 20:36:51 -04:00
Dmitry Ng b90ea4711e repo final state 2026-03-26 06:16:07 +03:00