From cd936e4c2b9237b44c2fbe8f7347f3f9e476c8bd Mon Sep 17 00:00:00 2001 From: Mitry Date: Mon, 2 Jun 2025 10:42:45 -0300 Subject: [PATCH 01/26] refactor struct --- .dockerignore | 1 - Makefile | 63 ++++++++++++++++++++++++----------------- README.md | 24 +++++++++------- docker-compose.test.yml | 6 +--- docker-compose.yml | 10 ++----- 5 files changed, 54 insertions(+), 50 deletions(-) diff --git a/.dockerignore b/.dockerignore index b686b699..83cc027f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,7 +4,6 @@ db venv __pycache__ -migrations file_store storage worker_tmp diff --git a/Makefile b/Makefile index 711ae97d..0fb72a0f 100644 --- a/Makefile +++ b/Makefile @@ -1,41 +1,52 @@ -prod: - docker compose up -d +include .env -prod-new: - docker compose up -d --build +DOCKER_IMAGE := dc_app +DB_CONTAINER := iss-main-db +PROD_FILE := -f docker-compose.yml +DEV_FILE := -f docker-compose.dev.yml +TEST_FILE := -f docker-compose.test.yml -prod-stop: - docker compose down +# MAIN +build: + docker compose ${PROD_FILE} build --no-cache -prod-restart: - make prod-stop && make prod +start: + docker compose ${PROD_FILE} up -d -dev: - docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d +stop: + docker compose ${PROD_FILE} down + +start-new: build start +restart: stop start -dev-new: - docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build +# DEV +dev: + docker compose ${PROD_FILE} ${DEV_FILE} up -d dev-stop: - docker compose -f docker-compose.yml -f docker-compose.dev.yml down + docker compose ${PROD_FILE} ${DEV_FILE} down + +dev-new: build dev +dev-restart: dev-stop dev -dev-restart: - make dev-stop && make dev +# TEST +test-start: + docker compose ${TEST_FILE} up -d -test: - docker compose -f docker-compose.test.yml up -d --build +test-build: + docker compose ${TEST_FILE} build --no-cache test-stop: - docker compose -f docker-compose.test.yml down + docker compose ${TEST_FILE} down -test-restart: - make test-stop && make test +test: test-build test-start +test-restart: test-stop test -appdb-dump-schema: - docker exec iss-main-db pg_dump -U postgres -d iss_app_db --schema-only > app_dump_schema +# UTILS +dump-schema: + docker exec ${DB_CONTAINER} pg_dump -U postgres -d ${DB_APP_DB_NAME} --schema-only > dump_schema -appdb-dump-data: - docker exec iss-main-db pg_dump -U postgres -d iss_app_db --data-only > app_dump_data +dump-data: + docker exec ${DB_CONTAINER} pg_dump -U postgres -d ${DB_APP_DB_NAME} --data-only > dump_data -dump-database: - make appdb-dump-schema && make appdb-dump-data +dump-all: dump-schema dump-data diff --git a/README.md b/README.md index f4f05ba5..aa3373d1 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,17 @@ # ISS Data Collection Tool -## Makefile convinient commands (**docker/docker-compose** and **.env file** are supposed to be set): +## Makefile commands (**docker/docker-compose** and **.env file** are supposed to be set): +- build project: + `make build` - start project: - `make prod` + `make start` - stop project: - `make prod-stop` + `make stop` - restart project: - `make prod-restart` + `make restart` - start project with rebuild: - `make prod-new` + `make start-new` - start development project: `make dev` - stop development project: @@ -25,11 +27,11 @@ - restart tests: `make test-restart` - dump main apps database schema: - `make appdb-dump-schema` + `make dump-schema` - dump main apps database data: - `make appdb-dump-data` + `make dump-data` - dump main apps database (schema and data separately): - `make dump-database` + `make dump-all` ## Prerequisites: @@ -63,7 +65,7 @@ Docker files: - Dockerfile.storage Command: -`docker-compose -f docker-compose.dev.yml up -d --build` +`docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build` ## Testing @@ -84,9 +86,9 @@ Available tests: `docker exec iss-test-storage python3 src/test.py` - Frontend: `docker exec iss-test-front npm test` -- Selenium Tests (browser emulation): +- Selenium Tests (browser emulation) (turned off as for now): `docker exec iss-tests python3 test.py` -- Python linter (no output means the lint test is passed): +- Python linter: `docker exec iss-tests flake8` - JavaScript linter: `docker exec iss-test-front npm run lint` diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 822b1b0d..94a23fa1 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -42,11 +42,7 @@ services: BACKEND_PORT: 8000 MAX_WORKER: 1 command: > - sh -c "python manage.py makemigrations user && - python manage.py makemigrations project && - python manage.py makemigrations attribute && - python manage.py makemigrations file && - python manage.py makemigrations archive && + sh -c "python manage.py makemigrations && python manage.py migrate && python manage.py createsuperuser --email=admin@example.ex --noinput && gunicorn --config './conf/gunicorn_conf.py' proj_back.wsgi:application" diff --git a/docker-compose.yml b/docker-compose.yml index 58829283..71d6be2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: image: postgres:15.3-alpine restart: always environment: - POSTGRES_DB: ${DB_APP_DB_NAME:-app_db} + POSTGRES_DB: ${DB_APP_DB_NAME} POSTGRES_HOST_AUTH_METHOD: ${DB_APP_AUTH_METHOD:-trust} volumes: - ./db:/var/lib/postgresql/data @@ -35,7 +35,7 @@ services: restart: always environment: DB_HOST: iss-main-db - DB_NAME: ${DB_APP_DB_NAME:-app_db} + DB_NAME: ${DB_APP_DB_NAME} APP_STORAGE_URL: iss-storage:${STORAGE_PORT:-9000} SERVER_ORIGINS: ${SERVER_ORIGINS:-localhost} SECRET_KEY: ${SECRET_KEY} @@ -46,11 +46,7 @@ services: depends_on: - iss-main-db command: > - sh -c "python manage.py makemigrations user && - python manage.py makemigrations project && - python manage.py makemigrations attribute && - python manage.py makemigrations file && - python manage.py makemigrations archive && + sh -c "python manage.py makemigrations && python manage.py migrate && python manage.py remove_tokens && gunicorn --config './conf/gunicorn_conf.py' proj_back.wsgi:application" From 1b09d096b698eb5655bb3db076ef7375b6519c3a Mon Sep 17 00:00:00 2001 From: Mitry Date: Mon, 2 Jun 2025 11:20:13 -0300 Subject: [PATCH 02/26] revert back command --- docker-compose.test.yml | 6 +++++- docker-compose.yml | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 94a23fa1..822b1b0d 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -42,7 +42,11 @@ services: BACKEND_PORT: 8000 MAX_WORKER: 1 command: > - sh -c "python manage.py makemigrations && + sh -c "python manage.py makemigrations user && + python manage.py makemigrations project && + python manage.py makemigrations attribute && + python manage.py makemigrations file && + python manage.py makemigrations archive && python manage.py migrate && python manage.py createsuperuser --email=admin@example.ex --noinput && gunicorn --config './conf/gunicorn_conf.py' proj_back.wsgi:application" diff --git a/docker-compose.yml b/docker-compose.yml index 71d6be2a..64e7d5ac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,7 +46,11 @@ services: depends_on: - iss-main-db command: > - sh -c "python manage.py makemigrations && + sh -c "python manage.py makemigrations user && + python manage.py makemigrations project && + python manage.py makemigrations attribute && + python manage.py makemigrations file && + python manage.py makemigrations archive && python manage.py migrate && python manage.py remove_tokens && gunicorn --config './conf/gunicorn_conf.py' proj_back.wsgi:application" From 9f7356016544d8cbbc21bc3b8192cedf6f88f6d3 Mon Sep 17 00:00:00 2001 From: Mitry Date: Tue, 3 Jun 2025 10:57:15 -0300 Subject: [PATCH 03/26] ref readme, add docs --- README.md | 207 ++++++++++++++++++++++------------------ docs/assets/example.png | Bin 0 -> 157083 bytes 2 files changed, 112 insertions(+), 95 deletions(-) create mode 100644 docs/assets/example.png diff --git a/README.md b/README.md index aa3373d1..4076620c 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,113 @@ +# [ADD BRIEF GIF] # ISS Data Collection Tool - -## Makefile commands (**docker/docker-compose** and **.env file** are supposed to be set): - -- build project: - `make build` -- start project: - `make start` -- stop project: - `make stop` -- restart project: - `make restart` -- start project with rebuild: - `make start-new` -- start development project: - `make dev` -- stop development project: - `make dev-stop` -- restart development project: - `make dev-restart` -- start project with rebuild: - `make dev-new` -- start tests: - `make test` -- stop tests: - `make test-stop` -- restart tests: - `make test-restart` -- dump main apps database schema: - `make dump-schema` -- dump main apps database data: - `make dump-data` -- dump main apps database (schema and data separately): - `make dump-all` - -## Prerequisites: - -- **docker/docker-compose** installed -- create and fill **.env** file from sample - -For local development copying sample is enough: -`cp .env.sample .env` - -## Running Application - -Docker Compose file: docker-compose.yml - -Docker files: - -- Dockerfile.backend -- Dockerfile.frontend -- Dockerfile.storage - -Command: -`docker-compose up -d --build` - -## Development - -Docker Compose file: docker-compose.dev.yml - -Docker files: - -- Dockerfile.backend -- Dockerfile.frontend -- Dockerfile.storage - -Command: -`docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build` - -## Testing - -Docker Compose file: docker-compose.test.yml - -Docker files: - -- Dockerfile.tests - -Command (rebuild is important): -`docker-compose -f docker-compose.test.yml up -d --build` - -Available tests: - -- Main Backend: - `docker exec iss-test-back ./manage.py test` -- Storage Backend: - `docker exec iss-test-storage python3 src/test.py` -- Frontend: - `docker exec iss-test-front npm test` -- Selenium Tests (browser emulation) (turned off as for now): - `docker exec iss-tests python3 test.py` -- Python linter: - `docker exec iss-tests flake8` -- JavaScript linter: - `docker exec iss-test-front npm run lint` -- JavaScript ts compiler checker: - `docker exec iss-test-front npm run compile` + + +An end-to-end dataset annotation and management system built for scale. Supports multi-role workflows, structured label taxonomies, validation cycles, goal tracking, and archive exports. Ideal for organizations building private, high-integrity datasets. + +πŸ›  Under active development. Suitable for internal deployments and pilot stages. + +## 🧩 Purpose + +This platform lets you: + +- Create projects with custom label systems (flat or hierarchical) +- Upload images and assign them to labeling schemas +- Delegate validation roles to users for correcting or reviewing annotations +- Define collection goals per label and track stats +- Export annotated datasets with filter options + +## βš™οΈ Architecture + +- **Main Backend:** Django + PostgreSQL +- **File Backend:** FastAPI + MongoDB (blob storage) +- **Task Queue:** Celery + Redis +- **Frontend:** React +- **Deployment:** Docker, Compose, Makefile-based workflow + +## πŸ“ Folder Structure (Top Level) + +- `backend-app/` β€” main Django app +- `frontend-app/` β€” React app +- `storage-app/` β€” FastAPI blob service +- `scripts/` β€” app handy tools +- `tests/` β€” global tests +- `nginx/`, `redis/` β€” infrastructure configs +- `Makefile` β€” common commands +- `docker-compose*.yml` β€” dev/test/prod setup + +## πŸš€ Getting Started + +### Prerequisites + +- Docker + Docker Compose installed +- `.env` file created from `.env.sample` + +```bash +cp .env.sample .env +``` + +### Build & Run +```bash +make build # build all services +make start # start in prod mode +make dev # start in dev mode +``` +Full command list available in the Makefile section below. + +## πŸ§ͺ Testing +Run with: +```bash +docker exec iss-test-back ./manage.py test # Main Backend +docker exec iss-test-storage python3 src/test.py # Storage Backend +docker exec iss-test-front npm test # Frontend +docker exec iss-tests flake8 # Python linter +docker exec iss-test-front npm run lint # JavaScript linter +docker exec iss-test-front npm run compile # JavaScript ts compiler checker +``` + +## πŸ“š Documentation & Examples + +See docs/ and examples/ (coming soon): + +Project setup guide +Label schema manual +API usage examples +Export format specs + +## πŸ› οΈ Makefile Commands + +General +```bash +make build # build all services +make start # start in prod mode +make stop # stop prod mode +make start-new # rebuild and start services in prod mode +make restart # stop and start in prod mode +``` + +Dev Mode +```bash +make dev # start in dev mode +make dev-stop # stop dev mode +make dev-new # rebuild and start services in dev mode +make dev-restart # stop and start in dev mode +``` + +Tests +```bash +make test # rebuild and start services in test mode +make test-start # start in test mode +make test-build # build test mode +make test-stop # stop test mode +make test-restart # stop and start services in test mode +``` + +Utils +```bash +make dump-schema # dump database schema +make dump-data # dump database data +make dump-all # dump database both schema and data +``` + +# [CONTACT US SECTION?] +# [LINKS SECTION?] diff --git a/docs/assets/example.png b/docs/assets/example.png new file mode 100644 index 0000000000000000000000000000000000000000..1a9de69ef8760debfc93310391a18e50284e500f GIT binary patch literal 157083 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 literal 0 HcmV?d00001 From a9bc97edab648ba42c393c946601b8581882ef09 Mon Sep 17 00:00:00 2001 From: Mitry Date: Tue, 3 Jun 2025 10:59:36 -0300 Subject: [PATCH 04/26] fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4076620c..e0bc539c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [ADD BRIEF GIF] # ISS Data Collection Tool - +example An end-to-end dataset annotation and management system built for scale. Supports multi-role workflows, structured label taxonomies, validation cycles, goal tracking, and archive exports. Ideal for organizations building private, high-integrity datasets. From 966b8b66ca6a938b1997f8e0411741c320dd4000 Mon Sep 17 00:00:00 2001 From: Mitry Date: Tue, 3 Jun 2025 11:16:15 -0300 Subject: [PATCH 05/26] docs --- README.md | 21 ++++++++++++++------- docs/downloads.md | 0 docs/goals.md | 0 docs/labels.md | 0 docs/projects.md | 0 docs/quickstart.md | 0 docs/roles.md | 0 docs/statistics.md | 0 docs/uploads.md | 0 docs/users.md | 0 10 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 docs/downloads.md create mode 100644 docs/goals.md create mode 100644 docs/labels.md create mode 100644 docs/projects.md create mode 100644 docs/quickstart.md create mode 100644 docs/roles.md create mode 100644 docs/statistics.md create mode 100644 docs/uploads.md create mode 100644 docs/users.md diff --git a/README.md b/README.md index e0bc539c..60bd058d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# [ADD BRIEF GIF] -# ISS Data Collection Tool example +# ISS Data Collection Tool + An end-to-end dataset annotation and management system built for scale. Supports multi-role workflows, structured label taxonomies, validation cycles, goal tracking, and archive exports. Ideal for organizations building private, high-integrity datasets. πŸ›  Under active development. Suitable for internal deployments and pilot stages. @@ -67,12 +67,19 @@ docker exec iss-test-front npm run compile # JavaScript ts compiler che ## πŸ“š Documentation & Examples -See docs/ and examples/ (coming soon): +See docs/: + +Project setup guide Label schema manual API usage examples Export format specs -Project setup guide -Label schema manual -API usage examples -Export format specs +- [Downloads](/docs/downloads.md) +- [Goals](/docs/goals.md) +- [Labels](/docs/labels.md) +- [Projects](/docs/projects.md) +- [Quickstart](/docs/quickstart.md) +- [Roles](/docs/roles.md) +- [Statistics](/docs/statistics.md) +- [Uploads](/docs/uploads.md) +- [Users](/docs/users.md) ## πŸ› οΈ Makefile Commands diff --git a/docs/downloads.md b/docs/downloads.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/goals.md b/docs/goals.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/labels.md b/docs/labels.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/projects.md b/docs/projects.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/roles.md b/docs/roles.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/statistics.md b/docs/statistics.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/uploads.md b/docs/uploads.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/users.md b/docs/users.md new file mode 100644 index 00000000..e69de29b From d6425c760ad894915604c7cf503615812a82e27a Mon Sep 17 00:00:00 2001 From: Mitry Date: Tue, 3 Jun 2025 11:31:57 -0300 Subject: [PATCH 06/26] ref --- README.md | 16 ++++++++-------- docs/assets/example.png | Bin 157083 -> 0 bytes 2 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 docs/assets/example.png diff --git a/README.md b/README.md index 60bd058d..b49d4556 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -example +example # ISS Data Collection Tool @@ -67,19 +67,19 @@ docker exec iss-test-front npm run compile # JavaScript ts compiler che ## πŸ“š Documentation & Examples -See docs/: +See [docs/](/docs): Project setup guide Label schema manual API usage examples Export format specs -- [Downloads](/docs/downloads.md) -- [Goals](/docs/goals.md) -- [Labels](/docs/labels.md) -- [Projects](/docs/projects.md) - [Quickstart](/docs/quickstart.md) +- [Projects](/docs/projects.md) +- [Labels](/docs/labels.md) +- [Users](/docs/users.md) - [Roles](/docs/roles.md) -- [Statistics](/docs/statistics.md) - [Uploads](/docs/uploads.md) -- [Users](/docs/users.md) +- [Goals](/docs/goals.md) +- [Statistics](/docs/statistics.md) +- [Downloads](/docs/downloads.md) ## πŸ› οΈ Makefile Commands diff --git a/docs/assets/example.png b/docs/assets/example.png deleted file mode 100644 index 1a9de69ef8760debfc93310391a18e50284e500f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157083 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 From 7c8b014196a68d084916060ba04b2bab403f3183 Mon Sep 17 00:00:00 2001 From: Mitry Date: Wed, 4 Jun 2025 14:31:29 -0300 Subject: [PATCH 07/26] docs --- Makefile | 3 + README.md | 16 ++-- docs/labels.md | 99 +++++++++++++++++++ docs/projects.md | 157 +++++++++++++++++++++++++++++++ docs/quickstart.md | 38 ++++++++ docs/users.md | 41 ++++++++ docs/{roles.md => validation.md} | 0 7 files changed, 344 insertions(+), 10 deletions(-) rename docs/{roles.md => validation.md} (100%) diff --git a/Makefile b/Makefile index 0fb72a0f..872eb576 100644 --- a/Makefile +++ b/Makefile @@ -50,3 +50,6 @@ dump-data: docker exec ${DB_CONTAINER} pg_dump -U postgres -d ${DB_APP_DB_NAME} --data-only > dump_data dump-all: dump-schema dump-data + +init-admin: + docker exec -it iss-back ./manage.py createsuperuser diff --git a/README.md b/README.md index b49d4556..74a03748 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,14 @@ An end-to-end dataset annotation and management system built for scale. Supports multi-role workflows, structured label taxonomies, validation cycles, goal tracking, and archive exports. Ideal for organizations building private, high-integrity datasets. -πŸ›  Under active development. Suitable for internal deployments and pilot stages. +πŸ›  Currently in active development. Ideal for internal use, pilots, and research-stage projects. ## 🧩 Purpose This platform lets you: - Create projects with custom label systems (flat or hierarchical) -- Upload images and assign them to labeling schemas +- Upload images/videos and assign them to labeling schemas - Delegate validation roles to users for correcting or reviewing annotations - Define collection goals per label and track stats - Export annotated datasets with filter options @@ -67,16 +67,14 @@ docker exec iss-test-front npm run compile # JavaScript ts compiler che ## πŸ“š Documentation & Examples -See [docs/](/docs): - -Project setup guide Label schema manual API usage examples Export format specs +See [docs/](/docs) for manuals and walkthroughs: - [Quickstart](/docs/quickstart.md) - [Projects](/docs/projects.md) - [Labels](/docs/labels.md) -- [Users](/docs/users.md) -- [Roles](/docs/roles.md) +- [Users and Roles](/docs/users.md) - [Uploads](/docs/uploads.md) +- [Validation](/docs/validation.md) - [Goals](/docs/goals.md) - [Statistics](/docs/statistics.md) - [Downloads](/docs/downloads.md) @@ -114,7 +112,5 @@ Utils make dump-schema # dump database schema make dump-data # dump database data make dump-all # dump database both schema and data +make init-admin # create new superuser ``` - -# [CONTACT US SECTION?] -# [LINKS SECTION?] diff --git a/docs/labels.md b/docs/labels.md index e69de29b..136a1787 100644 --- a/docs/labels.md +++ b/docs/labels.md @@ -0,0 +1,99 @@ +# 🧩 Labels + +Each project uses a label schema to annotate the data being collected These can be: + +- Flat or hierarchical +- Required or optional +- Single or multiple choice + +--- + +## πŸ› οΈ Defining a Schema + +1. When creating a project or later in the Project β†’ Edit tab + +labels + +2. Add Tree-like Levels + +labels_level + +3. Add Values per level, with optional nesting. Each value is an actual label used during annotation. + +labels_value + +4. Set flags like: + - required + - multiple choice + +labels_flags + +5. Each label value could have a payload. This is a meta information in valid json/string format. +You can set restricted flag which sets if payload is required +Examples: +- label payload +- {"field1": "value1", "type": 1, "list": ["metalist1", "metalist2"]} +- ["meta1", "meta2"] + +labels_payload + +6. You can do a quick renaming with special form. + +labels_rename + +7. You can change alignment of values. + +labels_align + +8. Deleting may be performed only when no media is assigned to such label or level of labels. +When you hit remove (`minus`) button - the popup will tell you if this item cannot be removed. +If you really want to remove it even when it's restricted you could change labeling at validation tab to remove association + +labels_delete + +9. Grouping +Each block represents a separate attribute tree (e.g., color, shape, type). +In order to add another label with different meaning you press "Add attribute" at the top. +I.E. each feature has its own tree / block/ + +To remove a group completely you have to delete all the levels. + +labels_add + +## πŸ“€ Applying Schema + +When [uploading data](/docs/uploads.md), you assign the schema: +- With special form to apply tree o the whole set you uploaded +- Or manually, item by item + +These methods can be used simultaneously + +labels_apply + +The label hierarchy defined in the project could be set several times by clicking `add object` button. +This will create a new block with its own hierarchy. +This might be useful if your image for example has several annotated objects like cars or animals. + +labels_apply_new + +Each group can be easily deleted or copied. + +labels_apply_del-cp + +## πŸ“ Validation Stage + +During [validation](/docs/validation.md), labels can be you have same tree you assigned on Upload stage with the same management. + +labels_validate + +## πŸ” Filtering + +At some pages there is an option to use Schema labels as filters. +The usage is almost the same as you apply labels to the media. +When you are done with tree click `select` button. + +labels_filter + +## βœ… Next Step + +[Users and Roles](/docs/users.md) diff --git a/docs/projects.md b/docs/projects.md index e69de29b..9f5c59eb 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -0,0 +1,157 @@ +# πŸ“ Projects + +Projects are the core unit of organization in the ISS Data Collection Tool. +Each project defines its own label system, goals, and data scope. + +project_main + +--- + +## πŸ”Ή What is a Project? + +A project groups: + +- [A labeling taxonomy (flat or hierarchical)](/docs/labels.md) +- [Uploaded images/videos](/docs/uploads.md) +- [Collection goals (per label)](/docs/goals.md) +- [Assigned users with roles](/docs/users.md) + +--- + +## πŸ“€ Creating a Project + +Only admin/superusers can create new projects via the UI or API. + +To create via UI: +1. Log in as an admin +2. Go to **Projects** section (/projects) +3. Click **create project** +4. Fill out: + - **Name of the project** + - **Project Description** + - **Label Schema** + +project_create + +Next you will be redirected back to list of projects. +Select your newly created one. + +Your project page will look like this: + +project_detail + +Each project has the following sections: +(admin users will see all sections; regular users will only see a subset) + +- Main info β†’ `/project/:id` +- upload data β†’ `/project/:id/upload` +- validate data β†’ `/project/:id/validate` +- goals β†’ `/project/:id/goals` +- statistics β†’ `/project/:id/stats` +- download data β†’ `/project/:id/download` +- edit β†’ `/project/:id/edit` + +More of that below + +--- + +## πŸ‘₯ Roles & Access + +Users are split by admin/ non admin ones. +Admins have full access to the whole application and items; +Non admin users by default don't have any access to project or its data +so you need to manually edit the permissions for it if needed. + +project_permissions + +See [Users & Roles](/docs/users.md) for how to manage users and set permissions + +--- + +## πŸ–ΌοΈ Uploading + +After creating you can upload images or videos. +After labeling and sending media to the server they will appear in validation section. +Note: media processing on the server side may cause a slight delay before visibility. + +upload + +See [Uploads](/docs/uploads.md) for how to upload media + +--- + +## πŸ“ Validation + +When you are done with uploading you can validate this data whether it's applicable to your project or not. +Labels could be corrected there too. + +validate + +See [Validation](/docs/validation.md) for how to validate/ see uploaded images + +--- + +## 🧩 Label Schema + +Each project might have a label schema, defining what’s being collected. Labels can be: + +- Flat list (e.g. `Car`, `Dog`, `Tree`) +- Hierarchical (e.g. `Animal > Dog > Labrador`) +- Required +- Multiple items + +labels + +See [Labels](/docs/labels.md) for how to create and assign them. + +--- + +## 🎯 Goals + +Optionally, you can define target counts for labels (e.g. "Need 100 images of `Dog`"). + +goals + +See [Goals](/docs/goals.md) for how to create and track them. + +--- + +## πŸ“Š Stats & Progress + +Each project has a brief dashboard shows the collected count grouped by: +- Labels +- Media type +- Validation type + +stats + +See [Statistics](/docs/statistics.md) + +--- + +## πŸ—ƒ Downloading Results + +You can export annotated datasets as `.zip` archives with optional filters + +download + +See [Downloads](/docs/downloads.md) for how to request archives + +--- + +## βš™οΈ Edit project + +You can at any time change project info, labels, permissions or delete the Project. +Deleting project won't cause to loose any data. It's just mark as hidden so it can be easily restored. + +After you are done with editing click `SUBMIT EDIT` + +User roles could set with dedicated button. + +project_edit + +--- + +## βœ… Next Step + +[Labels](/docs/labels.md) diff --git a/docs/quickstart.md b/docs/quickstart.md index e69de29b..7bf003ba 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -0,0 +1,38 @@ +# πŸš€ Quickstart + +This guide walks you through setting up and using ISS Data Collection Tool locally. + +--- + +## 1. Clone the Repository + +```bash +git clone https://github.com/ISSResearch/Data-Collection-Tool.git +cd data-collection-tool +cp .env.sample .env +make build +``` + +Make sure make, Docker, and Docker Compose are installed. +Edit the .env file to suit your environment before proceeding. + +## 2. Start in Prod Mode + +```bash +make start +``` + +This command starts all services in production mode using Docker Compose. +The project will be accessible at http://localhost:8000 (default port). + +## 3. Create admin user +```bash +make init-admin +``` + +You must create a superuser before accessing the UI. +Only admin users can currently create new projects and manage roles/permissions. +More about that in [Users and Roles](/docs/users.md) + +## βœ… Next Step +[Project](/docs/projects) diff --git a/docs/users.md b/docs/users.md index e69de29b..93534c34 100644 --- a/docs/users.md +++ b/docs/users.md @@ -0,0 +1,41 @@ +# πŸ‘₯ Users & Roles + +To operate the system, at least one user must be created via CLI using the make command. + +```bash +make init-admin +``` + +## πŸ”‘ Roles +Admin – full access across the system +Non Admin User / Collector – limited role. Permissions are configurable individually + +## 🧾 User Creation +Admins: must be created manually or upgraded from common user + +Self-registered users (via UI): start with no permissions + +register + +## Permissions +You must assign permissions manually on a per-project basis +Role assignment is granular and per project (can vary per user per project) + +To assign permission follow the Project β†’ Edit tab β†’ USER VISIBILITY path. +There you will find a list of common users with cross table of persmissions per project. +When you are done with ediiting click `SUBMIT VISIBILITY` to save the state. + +permissions + +Permission meaning: +- Can view project: project is accesable in list of project and could be entered. +- Can upload: has access to `uload` and `goal` tabs. Can upload media files to the project. +- Can view files: has access to `validation` tab. Can see only self uloaded media. +- Can validate: has acccess to `validation tab`. Can see all uploaded media and validate them. can change labels. +- Can view stats: has access to `statistics` tab. Can see stats per project. +- Can download: has access to `download` tab. Can download uploaded files. +- Can edit: has access to `edit` tab. Can change project's data. + +## βœ… Next Step + +[Uploads](/docs/uploads.md) diff --git a/docs/roles.md b/docs/validation.md similarity index 100% rename from docs/roles.md rename to docs/validation.md From f5d9bb96a11baf315294b5b5bab4f3015b3015e6 Mon Sep 17 00:00:00 2001 From: Mitry Date: Wed, 4 Jun 2025 14:35:42 -0300 Subject: [PATCH 08/26] ref --- docs/quickstart.md | 2 +- docs/users.md | 36 +++++++++++++++++------------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 7bf003ba..548cbb6a 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -35,4 +35,4 @@ Only admin users can currently create new projects and manage roles/permissions. More about that in [Users and Roles](/docs/users.md) ## βœ… Next Step -[Project](/docs/projects) +[Project](/docs/projects.md) diff --git a/docs/users.md b/docs/users.md index 93534c34..4fe2af46 100644 --- a/docs/users.md +++ b/docs/users.md @@ -1,40 +1,38 @@ # πŸ‘₯ Users & Roles -To operate the system, at least one user must be created via CLI using the make command. +To operate the system, at least one user must be created via CLI: ```bash make init-admin ``` ## πŸ”‘ Roles -Admin – full access across the system -Non Admin User / Collector – limited role. Permissions are configurable individually +- Admin – full access across the system +- Collector / Common User – limited role; permissions are set per project ## 🧾 User Creation -Admins: must be created manually or upgraded from common user - -Self-registered users (via UI): start with no permissions +- Admins: created manually or promoted from a common user +- Self-registered users: have no access until granted project-specific permissions register ## Permissions -You must assign permissions manually on a per-project basis -Role assignment is granular and per project (can vary per user per project) +Permissions are managed per project under: +Project β†’ Edit tab β†’ USER VISIBILITY -To assign permission follow the Project β†’ Edit tab β†’ USER VISIBILITY path. -There you will find a list of common users with cross table of persmissions per project. -When you are done with ediiting click `SUBMIT VISIBILITY` to save the state. +There you’ll see a list of users and a cross-table of permissions. +Click SUBMIT VISIBILITY to save changes. permissions -Permission meaning: -- Can view project: project is accesable in list of project and could be entered. -- Can upload: has access to `uload` and `goal` tabs. Can upload media files to the project. -- Can view files: has access to `validation` tab. Can see only self uloaded media. -- Can validate: has acccess to `validation tab`. Can see all uploaded media and validate them. can change labels. -- Can view stats: has access to `statistics` tab. Can see stats per project. -- Can download: has access to `download` tab. Can download uploaded files. -- Can edit: has access to `edit` tab. Can change project's data. +Permission types: +- Can view project – appears in list and is accessible +- Can upload – access to upload and goal tabs +- Can view files – access to validation; sees own uploads only +- Can validate – full access to validation; can edit labels +- Can view stats – access to statistics +- Can download – access to download +- Can edit – access to edit; can modify project ## βœ… Next Step From 395ddef7793dfe70c29c6f9cc2cd5c0e5007bd3e Mon Sep 17 00:00:00 2001 From: Mitry Date: Thu, 5 Jun 2025 14:47:59 -0300 Subject: [PATCH 09/26] docs --- docs/downloads.md | 48 +++++++++++++++++++++ docs/goals.md | 49 +++++++++++++++++++++ docs/statistics.md | 52 +++++++++++++++++++++++ docs/uploads.md | 76 +++++++++++++++++++++++++++++++++ docs/validation.md | 104 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 329 insertions(+) diff --git a/docs/downloads.md b/docs/downloads.md index e69de29b..f743817b 100644 --- a/docs/downloads.md +++ b/docs/downloads.md @@ -0,0 +1,48 @@ +# πŸ“₯ Downloads + +This section lets you download annotation results for a project. + +downloads + +## πŸŽ›οΈ Filter First + +Use the filter block above to define which files should be included in the export. + +downloads + +Once filters are set, you have two options: + +- `get archive`: + +This sends a request to build a downloadable archive with both the media and annotations. +Since it may include many files, this can take some time. + +- `get annotation`: + +This gives you only annotation dataβ€”no media included. +It includes all annotations matching the current filters. + +downloads_filters + +## πŸ“‹ Archive Table + +Once requested, all archives for the project are listed in a table below. + +Column `requested` shows the exact filters used to generate each archive. + +Click the download button to get the archive. + +downloads_table + +Once the process completes, the row turns green. This means you can get your archive. + +downloads_table_ok + +The archive process may fail. +In that case, the row turns red and the `result message` column shows what went wrong. + +downloads_table_fail + +## βž• Only New Files +When re-downloading later (e.g., the next day), you might want to include only new files. +Enable the `not downloaded before` flag to skip any files already included in past archives (based on the filters). diff --git a/docs/goals.md b/docs/goals.md index e69de29b..3656224c 100644 --- a/docs/goals.md +++ b/docs/goals.md @@ -0,0 +1,49 @@ +# 🎯 Goals + +This tab lets you define and track annotation targets for specific labels. + +goals + +--- + +## βž• Create a Goal +To define a goal + +1. Select a single label from any depth of the hierarchy. +2. Set the desired amount (how many annotated samples you want). +3. Define media weights for: + - πŸ–ΌοΈ Images (e.g., 1) + - 🎞️ Videos (e.g., 2) + +goals_create + +A goal is considered fulfilled when the weighted sum of validated data reaches the target: + +Example - Goal = 5, image weight = 1, video weight = 2 +You can complete the goal with 5 images, or 2 videos + 1 image, etc. + +--- + +## πŸ“Š Goal Table + +Active goals are listed with: + +- Label name +- Media weights +- Completed count +- Remaining amount +- Items on validation +- Validation progress + +The table is sorted by progress (least done on top) for better prioritization. + +goals_table + +Goals are hidden once fulfilled, to keep focus on active targets. +Toggle `show all` to view past goals or completed ones. + +--- + +## βœ… Next Step + +- [Statistics](/docs/statistics.md) diff --git a/docs/statistics.md b/docs/statistics.md index e69de29b..c93bdde4 100644 --- a/docs/statistics.md +++ b/docs/statistics.md @@ -0,0 +1,52 @@ +# πŸ“Š Stats + +This tab displays how labels are used and how annotations are validated, broken down by media type. + +stats + +--- + +## πŸ” Explore by Attribute or User + +You can group stats by: + +- Attribute (label and its nested structure) + +stats_label + +- User (who uploaded the data) + +stats_user + +Click on a parent row to expand child items. + +--- + +## πŸ“₯ Export Options + +Export the table in: + +- csv +- json +- xlsx + +stats_export + +Useful for further processing, reporting, or audits. + +--- + +## ↔️ Diff table + +The diff view splits data around a reference upload date. + +For example, setting `Diff from`: *2025-01-01* highlights what’s been uploaded since thenβ€”helpful for tracking changes over time. +No data is displayed until a reference date is selected. + +stats_diff + +--- + +## βœ… Next Step + +- [Downloads](/docs/downloads.md) diff --git a/docs/uploads.md b/docs/uploads.md index e69de29b..b56496e4 100644 --- a/docs/uploads.md +++ b/docs/uploads.md @@ -0,0 +1,76 @@ +# πŸ“€ Uploads + +uploads + +--- + +## πŸ” Select Files + +Upload images or videos. The UI shows thumbnails for each selected file. + +You can do that by: + - Drag and dropping your files + - Clicking `Add Media` button at the top left corner + +uploads_add +uploads_drop + +--- + +## 🧱 Annotate with Label Trees + +Each image/video could be annotated using a label schema you've defined earlier. + +You can: + +- `Add Object`: Adds another instance of the label tree per image (useful for multiple cars/objects in one image). +- `Delete Group`: Removes that label instance. +- `Copy Group`: Clones an existing label set within the item. + +uploads_groups + +## πŸŒ€ Batch Apply +The block on the left is for applying one label tree to all selected media. + +You define the values. +Hit `apply to all` β†’ auto-fills that tree across items. + +--- + +# πŸ” Interactive Media + +Click any image to zoom in. Useful for small objects or cluttered scenes. +This helps especially when annotating dense scenes or small objects. + +uploads_zoom + +--- + +## ⏳ Uploading + +Once done labeling: +Click `Upload` at the top right corner +Files get submitted to the server for processing. + +uploads_send + +You will be redirected to dedicated page showing the uploading state + +uploads_state + +Once all media marked either green or red according to success status +you are free to leave the page. + +uploads_finish + +Server will: + +- `Check` for duplicates +- `Store` label metadata +- `Delay` validation access until checks complete + +--- + +## βœ… Next Step + +- [Validation](/docs/validation.md) diff --git a/docs/validation.md b/docs/validation.md index e69de29b..ebbedcaf 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -0,0 +1,104 @@ +# βœ… Validation + +validation + +--- + +## πŸ“‚ Browse Uploads + +See all uploaded media waiting for review. +Left sidebar lists files – click to load one into view. +Item card contains: +- Short file id +- Upload user +- Upload date + +validation_left + + +- βœ… Green = approved +- ❌ Red = rejected +- πŸ”΅ Gray = untouched + +validation_status + +Use filters at the top to narrow by status, label, date or author. + +validation_filter + +--- + +## 🎯 Review & Confirm Labels + +Main canvas shows the media + label overlays. + +validation_middle + +Right sidebar holds the full label tree for that file along with file info such as: + +- File id +- Validation user +- Validation date +- Label tree +- Manage buttons + +validation_right + +You can: + +- View the media, move it, zoom +- Edit labels in-place +- Add/remove object groups +- Accept (βœ”) / Reject (βœ–) +- Download item + +--- + +## πŸ–±οΈ Quick Navigation + +Use these to streamline flow: + +- `← / β†’` β€” switch file +- `X` β€” reset canvas state +- `A` β€” accept current +- `D` β€” reject current +- Hover on thumbnail to preview, click ⬇️ to download. + +--- + +## 🧭 Done? + +Once all files are green or red you can go to the next page if some exists. +This could be done only manualy by now. + +--- + +## 🧬 Duplicate Detection System + +This system improves data integrity, avoids duplication of annotation work, and improves the consistency of image usage throughout the dataset lifecycle. + +The platform includes a **built-in duplicate detection mechanism** to streamline annotation workflows and prevents redundant effort. + + + +Key Features +- `Automatic Detection`: Upon image upload or validation, the system checks whether the image already exists in the current project. Detected duplicates are flagged immediately. +- `Visual Indicator`: Duplicates are visually marked with a large `DUPLICATE` tag displayed directly on the image view. + +validation_right + +- `Best Quality Selection`: When duplicates are found, the system automatically selects the **best quality version** (e.g., higher resolution) as the *primary reference image*. This version will be used upon downloading +- `Duplication Browser`: A new **"show duplicates"** button has been added, allowing quick access to all known duplicates of a given image, side-by-side. + +validation_right + +- `User Decisions`: Annotators can manually resolve duplicates. + +Duplicate checks currently operate **within a single project only**. +and will be **extended across all projects** in the future + +--- + +## βœ… Next Step + +- [Goals](/docs/goals.md) From 0ab6760cdd8f9f278192443659fc5a180ac68c4c Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 10:40:30 -0300 Subject: [PATCH 10/26] comment images --- README.md | 2 +- docs/downloads.md | 12 ++++++------ docs/goals.md | 6 +++--- docs/labels.md | 28 ++++++++++++++-------------- docs/projects.md | 22 +++++++++++----------- docs/statistics.md | 10 +++++----- docs/uploads.md | 16 ++++++++-------- docs/users.md | 4 ++-- docs/validation.md | 18 +++++++++--------- 9 files changed, 59 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 74a03748..591e314f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -example + # ISS Data Collection Tool diff --git a/docs/downloads.md b/docs/downloads.md index f743817b..8d938398 100644 --- a/docs/downloads.md +++ b/docs/downloads.md @@ -2,13 +2,13 @@ This section lets you download annotation results for a project. -downloads + ## πŸŽ›οΈ Filter First Use the filter block above to define which files should be included in the export. -downloads + Once filters are set, you have two options: @@ -22,7 +22,7 @@ Since it may include many files, this can take some time. This gives you only annotation dataβ€”no media included. It includes all annotations matching the current filters. -downloads_filters + ## πŸ“‹ Archive Table @@ -32,16 +32,16 @@ Column `requested` shows the exact filters used to generate each archive. Click the download button to get the archive. -downloads_table + Once the process completes, the row turns green. This means you can get your archive. -downloads_table_ok + The archive process may fail. In that case, the row turns red and the `result message` column shows what went wrong. -downloads_table_fail + ## βž• Only New Files When re-downloading later (e.g., the next day), you might want to include only new files. diff --git a/docs/goals.md b/docs/goals.md index 3656224c..08c1ffde 100644 --- a/docs/goals.md +++ b/docs/goals.md @@ -2,7 +2,7 @@ This tab lets you define and track annotation targets for specific labels. -goals + --- @@ -15,7 +15,7 @@ To define a goal - πŸ–ΌοΈ Images (e.g., 1) - 🎞️ Videos (e.g., 2) -goals_create + A goal is considered fulfilled when the weighted sum of validated data reaches the target: @@ -37,7 +37,7 @@ Active goals are listed with: The table is sorted by progress (least done on top) for better prioritization. -goals_table + Goals are hidden once fulfilled, to keep focus on active targets. Toggle `show all` to view past goals or completed ones. diff --git a/docs/labels.md b/docs/labels.md index 136a1787..d45538db 100644 --- a/docs/labels.md +++ b/docs/labels.md @@ -12,21 +12,21 @@ Each project uses a label schema to annotate the data being collected These can 1. When creating a project or later in the Project β†’ Edit tab -labels + 2. Add Tree-like Levels -labels_level + 3. Add Values per level, with optional nesting. Each value is an actual label used during annotation. -labels_value + 4. Set flags like: - required - multiple choice -labels_flags + 5. Each label value could have a payload. This is a meta information in valid json/string format. You can set restricted flag which sets if payload is required @@ -35,21 +35,21 @@ Examples: - {"field1": "value1", "type": 1, "list": ["metalist1", "metalist2"]} - ["meta1", "meta2"] -labels_payload + 6. You can do a quick renaming with special form. -labels_rename + 7. You can change alignment of values. -labels_align + 8. Deleting may be performed only when no media is assigned to such label or level of labels. When you hit remove (`minus`) button - the popup will tell you if this item cannot be removed. If you really want to remove it even when it's restricted you could change labeling at validation tab to remove association -labels_delete + 9. Grouping Each block represents a separate attribute tree (e.g., color, shape, type). @@ -58,7 +58,7 @@ I.E. each feature has its own tree / block/ To remove a group completely you have to delete all the levels. -labels_add + ## πŸ“€ Applying Schema @@ -68,23 +68,23 @@ When [uploading data](/docs/uploads.md), you assign the schema: These methods can be used simultaneously -labels_apply + The label hierarchy defined in the project could be set several times by clicking `add object` button. This will create a new block with its own hierarchy. This might be useful if your image for example has several annotated objects like cars or animals. -labels_apply_new + Each group can be easily deleted or copied. -labels_apply_del-cp + ## πŸ“ Validation Stage During [validation](/docs/validation.md), labels can be you have same tree you assigned on Upload stage with the same management. -labels_validate + ## πŸ” Filtering @@ -92,7 +92,7 @@ At some pages there is an option to use Schema labels as filters. The usage is almost the same as you apply labels to the media. When you are done with tree click `select` button. -labels_filter + ## βœ… Next Step diff --git a/docs/projects.md b/docs/projects.md index 9f5c59eb..1caf2460 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -3,7 +3,7 @@ Projects are the core unit of organization in the ISS Data Collection Tool. Each project defines its own label system, goals, and data scope. -project_main + --- @@ -31,14 +31,14 @@ To create via UI: - **Project Description** - **Label Schema** -project_create + Next you will be redirected back to list of projects. Select your newly created one. Your project page will look like this: -project_detail + Each project has the following sections: (admin users will see all sections; regular users will only see a subset) @@ -62,7 +62,7 @@ Admins have full access to the whole application and items; Non admin users by default don't have any access to project or its data so you need to manually edit the permissions for it if needed. -project_permissions + See [Users & Roles](/docs/users.md) for how to manage users and set permissions @@ -74,7 +74,7 @@ After creating you can upload images or videos. After labeling and sending media to the server they will appear in validation section. Note: media processing on the server side may cause a slight delay before visibility. -upload + See [Uploads](/docs/uploads.md) for how to upload media @@ -85,7 +85,7 @@ See [Uploads](/docs/uploads.md) for how to upload media When you are done with uploading you can validate this data whether it's applicable to your project or not. Labels could be corrected there too. -validate + See [Validation](/docs/validation.md) for how to validate/ see uploaded images @@ -100,7 +100,7 @@ Each project might have a label schema, defining what’s being collected. Label - Required - Multiple items -labels + See [Labels](/docs/labels.md) for how to create and assign them. @@ -110,7 +110,7 @@ See [Labels](/docs/labels.md) for how to create and assign them. Optionally, you can define target counts for labels (e.g. "Need 100 images of `Dog`"). -goals + See [Goals](/docs/goals.md) for how to create and track them. @@ -123,7 +123,7 @@ Each project has a brief dashboard shows the collected count grouped by: - Media type - Validation type -stats + See [Statistics](/docs/statistics.md) @@ -133,7 +133,7 @@ See [Statistics](/docs/statistics.md) You can export annotated datasets as `.zip` archives with optional filters -download + See [Downloads](/docs/downloads.md) for how to request archives @@ -148,7 +148,7 @@ After you are done with editing click `SUBMIT EDIT` User roles could set with dedicated button. -project_edit + --- diff --git a/docs/statistics.md b/docs/statistics.md index c93bdde4..e7760878 100644 --- a/docs/statistics.md +++ b/docs/statistics.md @@ -2,7 +2,7 @@ This tab displays how labels are used and how annotations are validated, broken down by media type. -stats + --- @@ -12,11 +12,11 @@ You can group stats by: - Attribute (label and its nested structure) -stats_label + - User (who uploaded the data) -stats_user + Click on a parent row to expand child items. @@ -30,7 +30,7 @@ Export the table in: - json - xlsx -stats_export + Useful for further processing, reporting, or audits. @@ -43,7 +43,7 @@ The diff view splits data around a reference upload date. For example, setting `Diff from`: *2025-01-01* highlights what’s been uploaded since thenβ€”helpful for tracking changes over time. No data is displayed until a reference date is selected. -stats_diff + --- diff --git a/docs/uploads.md b/docs/uploads.md index b56496e4..1de516aa 100644 --- a/docs/uploads.md +++ b/docs/uploads.md @@ -1,6 +1,6 @@ # πŸ“€ Uploads -uploads + --- @@ -12,8 +12,8 @@ You can do that by: - Drag and dropping your files - Clicking `Add Media` button at the top left corner -uploads_add -uploads_drop + + --- @@ -27,7 +27,7 @@ You can: - `Delete Group`: Removes that label instance. - `Copy Group`: Clones an existing label set within the item. -uploads_groups + ## πŸŒ€ Batch Apply The block on the left is for applying one label tree to all selected media. @@ -42,7 +42,7 @@ Hit `apply to all` β†’ auto-fills that tree across items. Click any image to zoom in. Useful for small objects or cluttered scenes. This helps especially when annotating dense scenes or small objects. -uploads_zoom + --- @@ -52,16 +52,16 @@ Once done labeling: Click `Upload` at the top right corner Files get submitted to the server for processing. -uploads_send + You will be redirected to dedicated page showing the uploading state -uploads_state + Once all media marked either green or red according to success status you are free to leave the page. -uploads_finish + Server will: diff --git a/docs/users.md b/docs/users.md index 4fe2af46..878ec056 100644 --- a/docs/users.md +++ b/docs/users.md @@ -14,7 +14,7 @@ make init-admin - Admins: created manually or promoted from a common user - Self-registered users: have no access until granted project-specific permissions -register + ## Permissions Permissions are managed per project under: @@ -23,7 +23,7 @@ Project β†’ Edit tab β†’ USER VISIBILITY There you’ll see a list of users and a cross-table of permissions. Click SUBMIT VISIBILITY to save changes. -permissions + Permission types: - Can view project – appears in list and is accessible diff --git a/docs/validation.md b/docs/validation.md index ebbedcaf..987108cb 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -1,6 +1,6 @@ # βœ… Validation -validation + --- @@ -13,18 +13,18 @@ Item card contains: - Upload user - Upload date -validation_left + - βœ… Green = approved - ❌ Red = rejected -- πŸ”΅ Gray = untouched +- πŸ”΅ Blue = untouched -validation_status + Use filters at the top to narrow by status, label, date or author. -validation_filter + --- @@ -32,7 +32,7 @@ Use filters at the top to narrow by status, label, date or author. Main canvas shows the media + label overlays. -validation_middle + Right sidebar holds the full label tree for that file along with file info such as: @@ -42,7 +42,7 @@ Right sidebar holds the full label tree for that file along with file info such - Label tree - Manage buttons -validation_right + You can: @@ -85,12 +85,12 @@ Key Features - `Automatic Detection`: Upon image upload or validation, the system checks whether the image already exists in the current project. Detected duplicates are flagged immediately. - `Visual Indicator`: Duplicates are visually marked with a large `DUPLICATE` tag displayed directly on the image view. -validation_right + - `Best Quality Selection`: When duplicates are found, the system automatically selects the **best quality version** (e.g., higher resolution) as the *primary reference image*. This version will be used upon downloading - `Duplication Browser`: A new **"show duplicates"** button has been added, allowing quick access to all known duplicates of a given image, side-by-side. -validation_right + - `User Decisions`: Annotators can manually resolve duplicates. From a7f6d45c0b0078a5078e838c5d6b986d992e19bc Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 10:47:51 -0300 Subject: [PATCH 11/26] ref readme --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 591e314f..e4ea40ec 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,29 @@ An end-to-end dataset annotation and management system built for scale. Supports πŸ›  Currently in active development. Ideal for internal use, pilots, and research-stage projects. -## 🧩 Purpose +## 🧩 Features This platform lets you: -- Create projects with custom label systems (flat or hierarchical) -- Upload images/videos and assign them to labeling schemas -- Delegate validation roles to users for correcting or reviewing annotations -- Define collection goals per label and track stats -- Export annotated datasets with filter options +- **Projects** with custom label systems +- **Uploading** images/videos and assigning them to labeling schemas +- Collection **Goals** +- Tracking **Stats** +- **Export** annotated datasets + +## πŸ“š Documentation & Examples + +See [docs/](/docs) for manuals and walkthroughs: + +- [Quickstart](/docs/quickstart.md) +- [Projects](/docs/projects.md) +- [Labels](/docs/labels.md) +- [Users and Roles](/docs/users.md) +- [Uploads](/docs/uploads.md) +- [Validation](/docs/validation.md) +- [Goals](/docs/goals.md) +- [Statistics](/docs/statistics.md) +- [Downloads](/docs/downloads.md) ## βš™οΈ Architecture @@ -65,20 +79,6 @@ docker exec iss-test-front npm run lint # JavaScript linter docker exec iss-test-front npm run compile # JavaScript ts compiler checker ``` -## πŸ“š Documentation & Examples - -See [docs/](/docs) for manuals and walkthroughs: - -- [Quickstart](/docs/quickstart.md) -- [Projects](/docs/projects.md) -- [Labels](/docs/labels.md) -- [Users and Roles](/docs/users.md) -- [Uploads](/docs/uploads.md) -- [Validation](/docs/validation.md) -- [Goals](/docs/goals.md) -- [Statistics](/docs/statistics.md) -- [Downloads](/docs/downloads.md) - ## πŸ› οΈ Makefile Commands General From 0826b02a3ba86aed2c03ac2902dbf4bb7865eeb3 Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 10:53:21 -0300 Subject: [PATCH 12/26] ref --- docs/projects.md | 20 -------------------- docs/quickstart.md | 19 +++++++++++++------ 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/docs/projects.md b/docs/projects.md index 1caf2460..a0cb1f59 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -5,8 +5,6 @@ Each project defines its own label system, goals, and data scope. ---- - ## πŸ”Ή What is a Project? A project groups: @@ -16,8 +14,6 @@ A project groups: - [Collection goals (per label)](/docs/goals.md) - [Assigned users with roles](/docs/users.md) ---- - ## πŸ“€ Creating a Project Only admin/superusers can create new projects via the UI or API. @@ -53,8 +49,6 @@ Each project has the following sections: More of that below ---- - ## πŸ‘₯ Roles & Access Users are split by admin/ non admin ones. @@ -66,8 +60,6 @@ so you need to manually edit the permissions for it if needed. See [Users & Roles](/docs/users.md) for how to manage users and set permissions ---- - ## πŸ–ΌοΈ Uploading After creating you can upload images or videos. @@ -78,8 +70,6 @@ Note: media processing on the server side may cause a slight delay before visibi See [Uploads](/docs/uploads.md) for how to upload media ---- - ## πŸ“ Validation When you are done with uploading you can validate this data whether it's applicable to your project or not. @@ -89,8 +79,6 @@ Labels could be corrected there too. See [Validation](/docs/validation.md) for how to validate/ see uploaded images ---- - ## 🧩 Label Schema Each project might have a label schema, defining what’s being collected. Labels can be: @@ -104,8 +92,6 @@ Each project might have a label schema, defining what’s being collected. Label See [Labels](/docs/labels.md) for how to create and assign them. ---- - ## 🎯 Goals Optionally, you can define target counts for labels (e.g. "Need 100 images of `Dog`"). @@ -114,8 +100,6 @@ Optionally, you can define target counts for labels (e.g. "Need 100 images of `D See [Goals](/docs/goals.md) for how to create and track them. ---- - ## πŸ“Š Stats & Progress Each project has a brief dashboard shows the collected count grouped by: @@ -127,8 +111,6 @@ Each project has a brief dashboard shows the collected count grouped by: See [Statistics](/docs/statistics.md) ---- - ## πŸ—ƒ Downloading Results You can export annotated datasets as `.zip` archives with optional filters @@ -137,8 +119,6 @@ You can export annotated datasets as `.zip` archives with optional filters See [Downloads](/docs/downloads.md) for how to request archives ---- - ## βš™οΈ Edit project You can at any time change project info, labels, permissions or delete the Project. diff --git a/docs/quickstart.md b/docs/quickstart.md index 548cbb6a..8ba92a05 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -9,23 +9,28 @@ This guide walks you through setting up and using ISS Data Collection Tool local ```bash git clone https://github.com/ISSResearch/Data-Collection-Tool.git cd data-collection-tool -cp .env.sample .env -make build ``` -Make sure make, Docker, and Docker Compose are installed. -Edit the .env file to suit your environment before proceeding. +## 2. Build images + +```bash +make build +``` -## 2. Start in Prod Mode +## 3. Start in Prod Mode ```bash +cp .env.sample .env make start ``` +Make sure make, Docker, and Docker Compose are installed. +Edit the .env file to suit your environment before proceeding. + This command starts all services in production mode using Docker Compose. The project will be accessible at http://localhost:8000 (default port). -## 3. Create admin user +## 4. Create admin user ```bash make init-admin ``` @@ -34,5 +39,7 @@ You must create a superuser before accessing the UI. Only admin users can currently create new projects and manage roles/permissions. More about that in [Users and Roles](/docs/users.md) +--- + ## βœ… Next Step [Project](/docs/projects.md) From f5d457f9c8f5aef2e4c6d80857aaefbbf510c3c9 Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 10:54:08 -0300 Subject: [PATCH 13/26] ref --- docs/quickstart.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 8ba92a05..9152cb20 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -2,8 +2,6 @@ This guide walks you through setting up and using ISS Data Collection Tool locally. ---- - ## 1. Clone the Repository ```bash @@ -41,5 +39,5 @@ More about that in [Users and Roles](/docs/users.md) --- -## βœ… Next Step +### βœ… Next Step [Project](/docs/projects.md) From 8e350318a5f701d82ea91e7b835c06a7a0b1f1af Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 10:59:55 -0300 Subject: [PATCH 14/26] ref --- docs/projects.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/projects.md b/docs/projects.md index a0cb1f59..0b905e68 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -16,9 +16,9 @@ A project groups: ## πŸ“€ Creating a Project -Only admin/superusers can create new projects via the UI or API. +Only [admin/superusers](#roles-access) can create new projects via the UI or API. -To create via UI: +To create a project: 1. Log in as an admin 2. Go to **Projects** section (/projects) 3. Click **create project** @@ -32,20 +32,18 @@ To create via UI: Next you will be redirected back to list of projects. Select your newly created one. -Your project page will look like this: - Each project has the following sections: (admin users will see all sections; regular users will only see a subset) -- Main info β†’ `/project/:id` -- upload data β†’ `/project/:id/upload` -- validate data β†’ `/project/:id/validate` -- goals β†’ `/project/:id/goals` -- statistics β†’ `/project/:id/stats` -- download data β†’ `/project/:id/download` -- edit β†’ `/project/:id/edit` +- **Main info** β†’ `/project/:id` +- [**upload data**](#uploading) β†’ `/project/:id/upload` +- [**validate data**](#validation) β†’ `/project/:id/validate` +- [**goals**](#goals) β†’ `/project/:id/goals` +- [**statistics**](#stats-progress) β†’ `/project/:id/stats` +- [**download data**](#downloading-results) β†’ `/project/:id/download` +- [**edit**](#edit-project) β†’ `/project/:id/edit` More of that below @@ -132,6 +130,6 @@ User roles could set with dedicated button. --- -## βœ… Next Step +### βœ… Next Step [Labels](/docs/labels.md) From 76ea9a3373d051ad7657054d5e3c03c5d4cc694e Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:02:19 -0300 Subject: [PATCH 15/26] fix --- docs/projects.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/projects.md b/docs/projects.md index 0b905e68..ea3abade 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -16,7 +16,7 @@ A project groups: ## πŸ“€ Creating a Project -Only [admin/superusers](#roles-access) can create new projects via the UI or API. +Only [admin/superusers](#-roles--access) can create new projects via the UI or API. To create a project: 1. Log in as an admin @@ -38,12 +38,12 @@ Each project has the following sections: (admin users will see all sections; regular users will only see a subset) - **Main info** β†’ `/project/:id` -- [**upload data**](#uploading) β†’ `/project/:id/upload` -- [**validate data**](#validation) β†’ `/project/:id/validate` -- [**goals**](#goals) β†’ `/project/:id/goals` -- [**statistics**](#stats-progress) β†’ `/project/:id/stats` -- [**download data**](#downloading-results) β†’ `/project/:id/download` -- [**edit**](#edit-project) β†’ `/project/:id/edit` +- [**upload data**](#-uploading) β†’ `/project/:id/upload` +- [**validate data**](#-validation) β†’ `/project/:id/validate` +- [**goals**](#-goals) β†’ `/project/:id/goals` +- [**statistics**](#-stats-progress) β†’ `/project/:id/stats` +- [**download data**](#-downloading-results) β†’ `/project/:id/download` +- [**edit**](#-edit-project) β†’ `/project/:id/edit` More of that below From 8e3638ff979768054dd154c89524766077ec408e Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:06:56 -0300 Subject: [PATCH 16/26] ref --- docs/projects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/projects.md b/docs/projects.md index ea3abade..bc9ee3ba 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -81,7 +81,7 @@ See [Validation](/docs/validation.md) for how to validate/ see uploaded images Each project might have a label schema, defining what’s being collected. Labels can be: -- Flat list (e.g. `Car`, `Dog`, `Tree`) +- Flat list (e.g. `Red`, `Green`, `Blue`) - Hierarchical (e.g. `Animal > Dog > Labrador`) - Required - Multiple items From 3290b8e3558052737f2a59e9d11aa4a084b68021 Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:11:23 -0300 Subject: [PATCH 17/26] ref --- docs/labels.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/labels.md b/docs/labels.md index d45538db..4652a071 100644 --- a/docs/labels.md +++ b/docs/labels.md @@ -6,54 +6,52 @@ Each project uses a label schema to annotate the data being collected These can - Required or optional - Single or multiple choice ---- - ## πŸ› οΈ Defining a Schema -1. When creating a project or later in the Project β†’ Edit tab +When creating a project or later in the Project β†’ Edit tab: -2. Add Tree-like Levels +1. Add Tree-like Levels -3. Add Values per level, with optional nesting. Each value is an actual label used during annotation. +2. Add Values per level, with optional nesting. Each value is an actual label used during annotation. -4. Set flags like: - - required - - multiple choice +3. Set flags like: + - `required` + - `multiple choice` -5. Each label value could have a payload. This is a meta information in valid json/string format. +4. Each label value could have a payload. This is a meta information in valid `json/string` format. You can set restricted flag which sets if payload is required Examples: -- label payload -- {"field1": "value1", "type": 1, "list": ["metalist1", "metalist2"]} -- ["meta1", "meta2"] +- `label payload` +- `{"field1": "value1", "type": 1, "list": ["metalist1", "metalist2"]}` +- `["meta1", "meta2"]` -6. You can do a quick renaming with special form. +5. You can do a quick renaming with special form. -7. You can change alignment of values. +6. You can change alignment of values. -8. Deleting may be performed only when no media is assigned to such label or level of labels. +7. Deleting may be performed only when no media is assigned to such label or level of labels. When you hit remove (`minus`) button - the popup will tell you if this item cannot be removed. If you really want to remove it even when it's restricted you could change labeling at validation tab to remove association -9. Grouping +8. Grouping Each block represents a separate attribute tree (e.g., color, shape, type). -In order to add another label with different meaning you press "Add attribute" at the top. +In order to add another label with different meaning you press `Add attribute` at the top. I.E. each feature has its own tree / block/ To remove a group completely you have to delete all the levels. @@ -94,6 +92,8 @@ When you are done with tree click `select` button. -## βœ… Next Step +--- + +### βœ… Next Step [Users and Roles](/docs/users.md) From 4a9befee3c15f95cb86c8fb5b92529888d2a50e3 Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:13:35 -0300 Subject: [PATCH 18/26] ref --- docs/users.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/users.md b/docs/users.md index 878ec056..a38567ea 100644 --- a/docs/users.md +++ b/docs/users.md @@ -7,8 +7,8 @@ make init-admin ``` ## πŸ”‘ Roles -- Admin – full access across the system -- Collector / Common User – limited role; permissions are set per project +- **Admin** – full access across the system +- **Collector** / Common User – limited role; permissions are set per project ## 🧾 User Creation - Admins: created manually or promoted from a common user @@ -18,22 +18,24 @@ make init-admin ## Permissions Permissions are managed per project under: -Project β†’ Edit tab β†’ USER VISIBILITY +Project β†’ Edit tab β†’ `USER VISIBILITY` There you’ll see a list of users and a cross-table of permissions. -Click SUBMIT VISIBILITY to save changes. +Click `SUBMIT VISIBILITY` to save changes. Permission types: -- Can view project – appears in list and is accessible -- Can upload – access to upload and goal tabs -- Can view files – access to validation; sees own uploads only -- Can validate – full access to validation; can edit labels -- Can view stats – access to statistics -- Can download – access to download -- Can edit – access to edit; can modify project - -## βœ… Next Step +- `Can view project` – appears in list and is accessible +- `Can upload` – access to upload and goal tabs +- `Can view files` – access to validation; sees own uploads only +- `Can validate` – full access to validation; can edit labels +- `Can view stats` – access to statistics +- `Can download` – access to download +- `Can edit` – access to edit; can modify project + +--- + +### βœ… Next Step [Uploads](/docs/uploads.md) From b8cd808b838fbd2be56d3b44e9d4d6c06cd47d32 Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:17:36 -0300 Subject: [PATCH 19/26] ref --- docs/uploads.md | 16 ++++--------- docs/validation.md | 57 ++++++++++++++++++---------------------------- 2 files changed, 26 insertions(+), 47 deletions(-) diff --git a/docs/uploads.md b/docs/uploads.md index 1de516aa..c0a9e1fa 100644 --- a/docs/uploads.md +++ b/docs/uploads.md @@ -2,8 +2,6 @@ ---- - ## πŸ” Select Files Upload images or videos. The UI shows thumbnails for each selected file. @@ -15,8 +13,6 @@ You can do that by: ---- - ## 🧱 Annotate with Label Trees Each image/video could be annotated using a label schema you've defined earlier. @@ -35,8 +31,6 @@ The block on the left is for applying one label tree to all selected media. You define the values. Hit `apply to all` β†’ auto-fills that tree across items. ---- - # πŸ” Interactive Media Click any image to zoom in. Useful for small objects or cluttered scenes. @@ -44,8 +38,6 @@ This helps especially when annotating dense scenes or small objects. ---- - ## ⏳ Uploading Once done labeling: @@ -65,12 +57,12 @@ you are free to leave the page. Server will: -- `Check` for duplicates -- `Store` label metadata -- `Delay` validation access until checks complete +- **Check** for duplicates +- **Store** label metadata +- **Delay** validation access until checks complete --- -## βœ… Next Step +### βœ… Next Step - [Validation](/docs/validation.md) diff --git a/docs/validation.md b/docs/validation.md index 987108cb..2b228ffc 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -2,23 +2,20 @@ ---- - ## πŸ“‚ Browse Uploads See all uploaded media waiting for review. Left sidebar lists files – click to load one into view. Item card contains: -- Short file id -- Upload user -- Upload date +- **Short file id** +- **Upload user** +- **Upload date** - -- βœ… Green = approved -- ❌ Red = rejected -- πŸ”΅ Blue = untouched +- βœ… Green = **approved** +- ❌ Red = **rejected** +- πŸ”΅ Blue = **untouched** @@ -26,8 +23,6 @@ Use filters at the top to narrow by status, label, date or author. ---- - ## 🎯 Review & Confirm Labels Main canvas shows the media + label overlays. @@ -36,23 +31,21 @@ Main canvas shows the media + label overlays. Right sidebar holds the full label tree for that file along with file info such as: -- File id -- Validation user -- Validation date -- Label tree -- Manage buttons +- **File id** +- **Validation user** +- **Validation date** +- **Label tree** +- **Manage buttons** You can: -- View the media, move it, zoom -- Edit labels in-place -- Add/remove object groups -- Accept (βœ”) / Reject (βœ–) -- Download item - ---- +- **View** the media, move it, zoom +- **Edit** labels in-place +- **Add**/remove object groups +- **Accept** (βœ”) / Reject (βœ–) +- **Download** item ## πŸ–±οΈ Quick Navigation @@ -64,41 +57,35 @@ Use these to streamline flow: - `D` β€” reject current - Hover on thumbnail to preview, click ⬇️ to download. ---- - ## 🧭 Done? Once all files are green or red you can go to the next page if some exists. This could be done only manualy by now. ---- - ## 🧬 Duplicate Detection System This system improves data integrity, avoids duplication of annotation work, and improves the consistency of image usage throughout the dataset lifecycle. The platform includes a **built-in duplicate detection mechanism** to streamline annotation workflows and prevents redundant effort. - - Key Features -- `Automatic Detection`: Upon image upload or validation, the system checks whether the image already exists in the current project. Detected duplicates are flagged immediately. -- `Visual Indicator`: Duplicates are visually marked with a large `DUPLICATE` tag displayed directly on the image view. +- **Automatic Detection**: Upon image upload or validation, the system checks whether the image already exists in the current project. Detected duplicates are flagged immediately. +- **Visual Indicator**: Duplicates are visually marked with a large `DUPLICATE` tag displayed directly on the image view. -- `Best Quality Selection`: When duplicates are found, the system automatically selects the **best quality version** (e.g., higher resolution) as the *primary reference image*. This version will be used upon downloading -- `Duplication Browser`: A new **"show duplicates"** button has been added, allowing quick access to all known duplicates of a given image, side-by-side. +- **Best Quality Selection**: When duplicates are found, the system automatically selects the **best quality version** (e.g., higher resolution) as the *primary reference image*. This version will be used upon downloading +- **Duplication Browser**: A new **"show duplicates"** button has been added, allowing quick access to all known duplicates of a given image, side-by-side. -- `User Decisions`: Annotators can manually resolve duplicates. +- **User Decisions**: Annotators can manually resolve duplicates. Duplicate checks currently operate **within a single project only**. and will be **extended across all projects** in the future --- -## βœ… Next Step +### βœ… Next Step - [Goals](/docs/goals.md) From 07906550371fd65abc7a50d4b8f73e78f083f313 Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:26:37 -0300 Subject: [PATCH 20/26] ref --- docs/goals.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/goals.md b/docs/goals.md index 08c1ffde..2daff327 100644 --- a/docs/goals.md +++ b/docs/goals.md @@ -4,8 +4,6 @@ This tab lets you define and track annotation targets for specific labels. ---- - ## βž• Create a Goal To define a goal @@ -22,18 +20,16 @@ A goal is considered fulfilled when the weighted sum of validated data reaches t Example - Goal = 5, image weight = 1, video weight = 2 You can complete the goal with 5 images, or 2 videos + 1 image, etc. ---- - ## πŸ“Š Goal Table Active goals are listed with: -- Label name -- Media weights -- Completed count -- Remaining amount -- Items on validation -- Validation progress +- **Label name** +- **Media weights** +- **Completed count** +- **Remaining amount** +- **Items on validation** +- **Validation progress** The table is sorted by progress (least done on top) for better prioritization. @@ -44,6 +40,6 @@ Toggle `show all` to view past goals or completed ones. --- -## βœ… Next Step +### βœ… Next Step - [Statistics](/docs/statistics.md) From 063e1c57222397f85eb1af180d66a60bb249817c Mon Sep 17 00:00:00 2001 From: Mitry Date: Fri, 6 Jun 2025 11:29:31 -0300 Subject: [PATCH 21/26] ref --- docs/downloads.md | 4 ++-- docs/goals.md | 6 +++--- docs/statistics.md | 20 +++++++------------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/docs/downloads.md b/docs/downloads.md index 8d938398..03f46329 100644 --- a/docs/downloads.md +++ b/docs/downloads.md @@ -28,7 +28,7 @@ It includes all annotations matching the current filters. Once requested, all archives for the project are listed in a table below. -Column `requested` shows the exact filters used to generate each archive. +Column **requested** shows the exact filters used to generate each archive. Click the download button to get the archive. @@ -39,7 +39,7 @@ Once the process completes, the row turns green. This means you can get your arc The archive process may fail. -In that case, the row turns red and the `result message` column shows what went wrong. +In that case, the row turns red and the **result message** column shows what went wrong. diff --git a/docs/goals.md b/docs/goals.md index 2daff327..b1e3ade5 100644 --- a/docs/goals.md +++ b/docs/goals.md @@ -7,9 +7,9 @@ This tab lets you define and track annotation targets for specific labels. ## βž• Create a Goal To define a goal -1. Select a single label from any depth of the hierarchy. -2. Set the desired amount (how many annotated samples you want). -3. Define media weights for: +1. Select a **single label** from any depth of the hierarchy. +2. Set the desired **amount** (how many annotated samples you want). +3. Define media **weights** for: - πŸ–ΌοΈ Images (e.g., 1) - 🎞️ Videos (e.g., 2) diff --git a/docs/statistics.md b/docs/statistics.md index e7760878..693e4cdd 100644 --- a/docs/statistics.md +++ b/docs/statistics.md @@ -4,38 +4,32 @@ This tab displays how labels are used and how annotations are validated, broken ---- - ## πŸ” Explore by Attribute or User You can group stats by: -- Attribute (label and its nested structure) +- **Attribute** (label and its nested structure) -- User (who uploaded the data) +- **User** (who uploaded the data) -Click on a parent row to expand child items. - ---- +Click on a `parent row` to expand child items. ## πŸ“₯ Export Options Export the table in: -- csv -- json -- xlsx +- `csv` +- `json` +- `xlsx` Useful for further processing, reporting, or audits. ---- - ## ↔️ Diff table The diff view splits data around a reference upload date. @@ -47,6 +41,6 @@ No data is displayed until a reference date is selected. --- -## βœ… Next Step +### βœ… Next Step - [Downloads](/docs/downloads.md) From 87ea16a6bc86a08aa166a472fbbae8621948990a Mon Sep 17 00:00:00 2001 From: Mitrii Ziuzin Date: Sun, 8 Jun 2025 08:07:50 -0300 Subject: [PATCH 22/26] Update docs/downloads.md Co-authored-by: Slava Eliseev --- docs/downloads.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/downloads.md b/docs/downloads.md index 03f46329..20146588 100644 --- a/docs/downloads.md +++ b/docs/downloads.md @@ -1,6 +1,6 @@ # πŸ“₯ Downloads -This section lets you download annotation results for a project. +This section lets you download collected data for a project. From f358b5ef75e2a03b4ee8e999f548bc43c0475c0f Mon Sep 17 00:00:00 2001 From: Mitrii Ziuzin Date: Sun, 8 Jun 2025 08:08:00 -0300 Subject: [PATCH 23/26] Update docs/goals.md Co-authored-by: Slava Eliseev --- docs/goals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/goals.md b/docs/goals.md index b1e3ade5..d6ebc667 100644 --- a/docs/goals.md +++ b/docs/goals.md @@ -1,6 +1,6 @@ # 🎯 Goals -This tab lets you define and track annotation targets for specific labels. +This tab lets you define and track collection targets for specific labels. From 523b6c75c1e77a0656730cccb4a8b3f35f548535 Mon Sep 17 00:00:00 2001 From: Mitrii Ziuzin Date: Sun, 8 Jun 2025 08:08:17 -0300 Subject: [PATCH 24/26] Update docs/labels.md Co-authored-by: Slava Eliseev --- docs/labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/labels.md b/docs/labels.md index 4652a071..068acdce 100644 --- a/docs/labels.md +++ b/docs/labels.md @@ -1,6 +1,6 @@ # 🧩 Labels -Each project uses a label schema to annotate the data being collected These can be: +Each project uses a label schema to annotate collected data. Labels help ensure even data collection and reduce future class imbalance. These can include: - Flat or hierarchical - Required or optional From 45af7fda0ae09bdcbec87e758a76482b6694f66a Mon Sep 17 00:00:00 2001 From: Mitrii Ziuzin Date: Sun, 8 Jun 2025 08:08:34 -0300 Subject: [PATCH 25/26] Update README.md Co-authored-by: Slava Eliseev --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e4ea40ec..ed5e6d5a 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,14 @@ An end-to-end dataset annotation and management system built for scale. Supports ## 🧩 Features -This platform lets you: - -- **Projects** with custom label systems -- **Uploading** images/videos and assigning them to labeling schemas -- Collection **Goals** -- Tracking **Stats** -- **Export** annotated datasets +This platform enables you to: + +- Create projects with custom label systems +- Upload images/videos and assign them to labeling schemas +- validate uploaded files +- Set collection goals +- Track progress with stats +- Export data ## πŸ“š Documentation & Examples From ca88fab4cb85dcc232b0553cc2e834b7bfb33af5 Mon Sep 17 00:00:00 2001 From: Mitrii Ziuzin Date: Sun, 8 Jun 2025 08:08:42 -0300 Subject: [PATCH 26/26] Update README.md Co-authored-by: Slava Eliseev --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed5e6d5a..e6505aed 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # ISS Data Collection Tool -An end-to-end dataset annotation and management system built for scale. Supports multi-role workflows, structured label taxonomies, validation cycles, goal tracking, and archive exports. Ideal for organizations building private, high-integrity datasets. +An end-to-end dataset collection system designed for scalability. Supports multi-role workflows, structured label taxonomies, validation cycles, goal tracking, and archive exports. Ideal for organizations building private, high-integrity datasets with distributed teams of data collectors. πŸ›  Currently in active development. Ideal for internal use, pilots, and research-stage projects.