Commit Graph

36 Commits

Author SHA1 Message Date
ld 63ede5c237 refactor(api): enforce protocol-neutral service boundaries
- refactor: move HTTP status and DTO concerns out of model and service
  layers into API and handler code.
- feat: add admin service boundary and route auth through services
  instead of direct repository access.
- test: add architecture and error tests covering package boundaries,
  redaction, and service behavior.
- docs: record the protocol-neutral boundary decision and update
  architecture and roadmap notes.
2026-07-05 23:30:17 +08:00
ld 28e17a5b08 refactor: add AppError helpers and harden upload/download error handling
- refactor: replace inline AppError literals with model.New*Error
  constructors in service and handler layers
- feat: PromoteStaged falls back to copy/delete when os.Rename returns
  EXDEV (cross-device link)
- fix: upload error messages no longer leak internal multipart field
  names or parser implementation details
- fix: upload size violations are converted to domain error
  ErrUploadTooLarge at the handler boundary
- fix: download logs error and size mismatch when io.Copy fails or
  writes fewer bytes than expected
- test: add tests for field name leak prevention, parser error
  sanitization, read errors after response start, and EXDEV fallback
2026-07-05 17:35:34 +08:00
ld fc2b9312fa docs: clarify conventional commit body blank-line rule 2026-07-05 17:18:59 +08:00
ld b988b4b15e fix(file)!: stream uploads through staged storage
- fix: replace multipart form parsing with streaming multipart reads and
  apply request body limits when max_upload_size is configured.
- refactor: route uploads through staging paths before promotion to
  long-term data paths, keeping incomplete uploads out of durable
  storage records.
- test: cover oversized uploads, unlimited uploads, staged cleanup, and
  local storage promotion boundaries.
- docs: document the staged upload model and multipart parent_id query
  parameter.
2026-07-05 17:18:19 +08:00
ld bfeb4b26e4 docs(AGENTS.md): clarify and tighten Git workflow instructions 2026-07-05 15:34:22 +08:00
ld 17e346836c docs(AGENTS.md): add Git Version Control section 2026-07-05 13:54:16 +08:00
ld 5eeb37389b fix(config): harden default JWT secret
Replace known development JWT secret placeholders with an ephemeral runtime secret during config loading.

Return LoadInfo so startup can warn when token persistence depends on a stable configured secret.

Update config docs and tests for default, legacy placeholder, custom, env, and empty secret behavior.
2026-07-05 13:25:44 +08:00
ld 7b6587a951 test(handler): TDD tests for AdminHandler user CRUD and visibility
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-04 17:31:01 +08:00
ld 3daad379e0 test(server): add admin route integration test 2026-07-04 17:23:35 +08:00
ld e04e39bea8 feat(svc): implement soft-delete in FileService
Delete now performs soft-delete (status='user_deleted') instead of physical deletion.

Removes storage content deletion — files are preserved on disk after soft-delete.

Second delete on already-deleted file returns nil (idempotent).

Add tests: SoftDelete, SoftDeleteKeepsStorage, SoftDeleteIdempotent, SoftDeleteForbidden.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-04 17:20:34 +08:00
ld ac98b5ddbd feat(middleware): add AdminRequired authorization middleware
AdminRequired gates admin endpoints by checking user IsAdmin flag.

Placed AFTER AuthRequired; fetches user from repository, returns 403 for non-admins.

Soft-deleted users are rejected with 401 since FindByID excludes them.

Tests: admin passes, non-admin forbidden, soft-deleted admin rejected, missing user ID.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-04 17:20:30 +08:00
ld 032f716e49 feat(repo): add soft-delete with status filter to file queries
File repository now filters by status=active in all query methods (FindByID, FindByUserID, FindByParentID, FindByNameAndParent).

Delete now performs soft-delete by setting status to 'user_deleted' instead of physical row deletion.

Add ListIncludeDeleted to UserRepository for admin views of all users.

Add tests: StatusFilter, SoftDelete, DeleteIdempotent, StatusFilterCount.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-04 17:20:22 +08:00
ld a8078f787c feat(model): add Status field and constants to User and File
Add Status field (gorm, indexed, default active) to both User and File models.

Add User status constants: StatusActive, StatusAdminDeleted.

Add File status constant: StatusUserDeleted.

Add tests verifying Status field is excluded from JSON serialization.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-04 17:20:14 +08:00
ld 170e54495d feat(handler): add AdminHandler with admin routes 2026-07-04 17:18:23 +08:00
ld 118b7e4d2a feat(svc): reject disabled users in Login, LoginWithPasskey, and Refresh 2026-07-04 17:13:02 +08:00
ld bff131ba42 feat(repo): soft-delete User with status filter on queries 2026-07-04 17:08:10 +08:00
ld 53bd473861 Add structured logging with request ID middleware 2026-07-04 16:24:37 +08:00
ld 1dfccf513a Add structured logging and centralized error handling
- Initialize slog in the serve command with terminal/file support
- Introduce `AppError` with HTTP status for unified service-layer errors
- Replace ad-hoc `api.Error` calls with `api.RespondError`
- Wrap internal errors with `model.NewInternalError` and add reference
  IDs
- Add `RequestID` middleware and switch router from `gin.Default` to
  `gin.New`
2026-07-04 16:24:22 +08:00
ld a78d43b166 Remove client MIME type parameter from Upload
- Fix: Always detect MIME type server-side from file content instead of
  trusting or forwarding the client-supplied value.
2026-06-24 20:27:22 +08:00
ld be4fcad605 Refactor handlers to use MustGetUserID
- Fix: replace repeated authorization checks in handlers with the new
  MustGetUserID helper, which panics if the user ID is missing. This
  simplifies handler code by eliminating redundant error handling.
- Tests: update auth tests to verify the panic behavior in unprotected
  routes.
2026-06-24 14:43:38 +08:00
ld a289130dcd Fix isSubPath to allow filenames starting with ".." 2026-06-24 14:28:32 +08:00
ld e2af482cc9 Add file management API with local storage backend
- Implement FileHandler with CRUD operations for files/directories
- Add FileService with business logic and SHA-256 hashing
- Create LocalStorage backend for filesystem persistence
- Add database repository with pagination and name uniqueness
  constraints
- Configure max upload size in storage settings
- Include comprehensive tests for all layers
2026-06-24 14:08:57 +08:00
ld eaa31efd64 Update architecture and decisions docs with auth refinements 2026-05-01 01:27:13 +08:00
ld b0356bf103 Refactor auth handler into separate account handler 2026-04-29 17:36:04 +08:00
ld 697cc979c8 Merge authentication system and database layer implementation. 2026-04-29 17:09:20 +08:00
ld f4212cddf0 Change config JWT duration fields to time.Duration
- fix: The AccessTTL and RefreshTTL fields in JWTConfig now use
  time.Duration type directly instead of string with ParseDuration
  methods. The config validation now checks for positive durations
  rather than parsing strings.
2026-04-29 17:02:49 +08:00
ld b4ab864f80 Add token type to JWT claims for access/refresh distinction
- Add TokenType enum and include in Claims struct
- GenerateRefreshToken now creates tokens with TokenRefresh type
- AuthRequired middleware rejects refresh tokens
- AuthService.Refresh validates token type
- Tests verify type validation
2026-04-29 16:55:18 +08:00
ld 712171230b Add JWT and UUID dependencies in go.sum
- Unexpectedly ignored in previous commit.
2026-04-29 11:51:20 +08:00
ld 3eeb9f6d26 Implement JWT authentication and app passkey support
- Add JWT token generation and validation
- Implement bcrypt password hashing
- Create auth service with register/login/refresh/logout
- Add app passkey generation and management
- Implement protected routes and auth middleware
- Add comprehensive tests for new functionality
2026-04-29 11:50:09 +08:00
ld 901a769ee7 Complete foundational data layer with repository implementation
- Add GORM dependencies for SQLite and PostgreSQL
- Create domain models (User, Session, File) with common errors
- Implement repository interfaces and database layer with migrations
- Update WebApp to bootstrap with database and repositories
- Add comprehensive unit tests for repository methods
- Update config structure to support multiple database drivers
- Extend AGENTS.md with debugging principles and dependency rules
2026-04-28 13:32:33 +08:00
ld f57f6c8f35 Update architecture and roadmap status icons. 2026-04-27 23:44:59 +08:00
ld d4d7495ffb Refactor router setup to split routes by auth/protected boundary 2026-04-27 23:30:17 +08:00
ld 7fb125ea87 Implement web API foundation
Add application container, Gin router, graceful shutdown handler,
and version endpoint. This establishes the skeleton for the WebDisk
HTTP API as described in the architecture.

- Add internal/app/WebApp for runtime dependencies and version
- Add internal/server/router with GET /api/v1/version route
- Add graceful shutdown runner with signal handling in cmd/serve
- Add internal/api/ErrorResponse for standard HTTP error body
- Update roadmap, architecture, and decisions documentation
2026-04-27 23:06:06 +08:00
ld c0c34eb914 Change JWT TTL config from duration to string for flexibility
- The mapstructure library is no longer needed for direct duration
  parsing since we now store TTLs as string durations (e.g., "15m",
  "168h") and parse them on demand via helper methods.
- This allows more flexible duration formats in configuration and moves
  the parsing responsibility to the JWT config struct itself.
2026-04-27 17:15:16 +08:00
ld 54f0deadbc Add initial framework of configuration.
feat: configuration file system of app.

Note: still work in progress.
2026-04-27 16:55:58 +08:00
ld e8a0c48658 Initialize project skeleton with CLI and documentation
Add initial project structure including:
- Go module with Cobra CLI dependency
- Root command and main entrypoint
- Basic documentation (README, AGENTS.md, architecture, decisions,
  development, roadmap)
- Configuration example and gitignore
- Tool version management with mise
- Comprehensive project rules and conventions
2026-04-25 17:18:16 +00:00