Commit Graph
20 Commits
Author SHA1 Message Date
kolaente 1f79a8e01a fix(migration): reject repeated csv column mappings, cap labels per row
- Reject a config that maps a column more than once, already when the
  import is started or previewed.
- Import repeated labels of a row once and reject rows with more than
  MaxLabelsPerTask (100) labels.
- Count items while converting rows so a file over the import item limit
  fails before the whole structure is built.
- Walk mappings sorted by column so a row only visits the cells it has.
2026-11-05 15:42:45 +01:00
kolaente 3830d2277c fix(migration): cap views per project on import 2026-11-03 23:41:40 +01:00
kolaente a89f7dd596 fix(migration): bind oauth migration callbacks to the user who requested the auth url 2026-10-20 15:13:02 +02:00
kolaente bf8859bab3 fix(migration): cap the number of items one import may create 2026-10-20 15:13:02 +02:00
kolaenteandTink 3dc5c72904 refactor(migration): parse the csv import config once per request
The config was unmarshalled up front purely to produce a 400, then parsed
again by SetOptions, and a third time in the background job. Drop the
throwaway parse and give SetOptions a domain error that maps to 400 on
its own.
2026-09-15 16:59:37 +02:00
kolaente 93fa646485 fix(migration): return 400 instead of 500 for broken vikunja exports
Unsafe paths, unusable file ids, a missing or unparseable VERSION and
unreadable data/filter json all describe a broken upload, not a server
fault, but they were raw fmt.Errorf values and surfaced as a 500. They now
return ErrInvalidImportFile; an export from a version we can no longer
read gets its own ErrImportFromUnsupportedVersion (14013) so clients can
tell the two apart. The http messages stay generic and never echo a path
from the archive.
2026-09-06 00:12:30 +02:00
kolaente 4090a3de2a fix(migration)!: move zip/empty file error codes off the api token codes
ErrCodeNotAZipFile and ErrCodeFileIsEmpty shared 14001 and 14002 with
ErrCodeAPITokenInvalid and ErrCodeInvalidAPITokenPermission, so clients
mapping codes to messages rendered the api token text for a failed import.
The api token codes are the older ones, so the migration errors move to
14011 and 14012.

BREAKING CHANGE: a failed import now returns 14011 instead of 14001 and
14012 instead of 14002.
2026-09-06 00:12:30 +02:00
kolaente 7d1aee8d0d fix(migration): use 14010 for ErrInvalidImportFile, 14008 is taken 2026-09-05 20:24:56 +02:00
kolaente a0ab6070eb fix(migration): return 400 for unparseable import files
A WeKan JSON export saved with a UTF-8 BOM made encoding/json return a raw
*json.SyntaxError from the migrator, which the shared error handler turned into
a 500 and forwarded to Sentry. Map decode failures of the uploaded file to a
400 in RunFileMigration (shared by v1 and v2), and skip a leading BOM so an
otherwise valid export imports instead of being rejected.

Fixes API-CLOUD-4B
2026-09-05 20:24:56 +02:00
kolaente d388b9d6b9 fix(migration): use 14009 for ErrNoDataFileInZip to avoid clashing with #3745 2026-09-05 11:58:40 +02:00
kolaente 74bb916f7c fix(migration): return 400 when an import zip has no data file 2026-09-05 11:58:40 +02:00
kolaente 86260fcdc0 feat(migration): typed error for failed upstream requests
Non-2xx responses from the service we migrate from were plain fmt.Errorf
values, so callers could not tell an upstream problem apart from a bug.
ErrUpstreamRequestFailed carries the migrator, status code and a truncated
body and is now returned by the shared http helpers, microsoft-todo,
todoist and planka.
2026-09-05 11:55:07 +02:00
kolaente c41a04d811 fix(migration): cap csv rows while decoding 2026-08-31 18:37:03 +02:00
kolaente 784f388252 fix(migration): serialize imports per user 2026-08-31 18:37:03 +02:00
kolaenteandkolaente 9c3c1047ac feat(api/v2): port OAuth migrators (Todoist, Trello, Microsoft To-Do)
Add /api/v2 auth/status/migrate endpoints for the three OAuth-based
migrators. One generic helper registers all three ops per migrator
behind its static config gate, so there's no copy-pasted block per
migrator.

The migrate kick-off orchestration (already-running guard + event
dispatch) is extracted into migrationHandler.StartMigration so v1 and
v2 share it; v1's wire output is unchanged. The guard now surfaces as a
typed migration.ErrMigrationAlreadyRunning (412) so v2 can translate it
through the standard error bridge.
2026-06-11 18:35:55 +00:00
Claudeandkolaente f555762def feat(migration): add generic CSV import with column mapping
Add a new CSV migration module that allows users to import tasks from
any CSV file with custom column mapping and parsing options.

Backend changes:
- New CSV migrator module with detection, preview, and import endpoints
- Auto-detection of delimiter, quote character, and date format
- Suggested column mappings based on column name patterns
- Transactional import using InsertFromStructure

Frontend changes:
- New CSV migration UI with two-step flow (upload -> mapping -> import)
- Column mapping selectors for all task attributes
- Live preview showing first 5 tasks with current mapping
- Parsing option controls for delimiter and date format

The CSV migrator creates a parent "Imported from CSV" project with
child projects based on the project column if provided, or a default
"Tasks" project for tasks without a specified project.
2026-04-07 15:20:06 +00:00
Dominik PschenitschniandGitHub 296577a875 fix: correct license header references (#882)
See originals:
- https://www.gnu.org/licenses/agpl-3.0.txt
- https://www.gnu.org/licenses/gpl-3.0.txt
2025-06-10 12:18:38 +02:00
kolaente 23d2814b94 fix(migration): check if the provided file is a valid csv before importing 2025-03-21 17:53:05 +01:00
kolaente d19a93dece fix(migration): check if uploaded csv is empty 2025-03-21 17:48:08 +01:00
kolaente 3d5d17336e fix(migration): return proper error when uploaded file is not a zip file
Resolves https://vikunja.sentry.io/share/issue/73a7b6f60b3e446e949d072016f31c22/
2025-01-09 14:32:24 +01:00