Skip to content

Commit 2a93ac6

Browse files
Squashed history before last 100 commits
1 parent 4049d78 commit 2a93ac6

File tree

116 files changed

+2985
-1091
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+2985
-1091
lines changed

.dockerignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
db
55
venv
66
__pycache__
7-
migrations
87
file_store
98
storage
109
worker_tmp

Makefile

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,55 @@
1-
prod:
2-
docker compose up -d
1+
include .env
32

4-
prod-new:
5-
docker compose up -d --build
3+
DOCKER_IMAGE := dc_app
4+
DB_CONTAINER := iss-main-db
5+
PROD_FILE := -f docker-compose.yml
6+
DEV_FILE := -f docker-compose.dev.yml
7+
TEST_FILE := -f docker-compose.test.yml
68

7-
prod-stop:
8-
docker compose down
9+
# MAIN
10+
build:
11+
docker compose ${PROD_FILE} build --no-cache
912

10-
prod-restart:
11-
make prod-stop && make prod
13+
start:
14+
docker compose ${PROD_FILE} up -d
1215

13-
dev:
14-
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
16+
stop:
17+
docker compose ${PROD_FILE} down
18+
19+
start-new: build start
20+
restart: stop start
1521

16-
dev-new:
17-
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
22+
# DEV
23+
dev:
24+
docker compose ${PROD_FILE} ${DEV_FILE} up -d
1825

1926
dev-stop:
20-
docker compose -f docker-compose.yml -f docker-compose.dev.yml down
27+
docker compose ${PROD_FILE} ${DEV_FILE} down
2128

22-
dev-restart:
23-
make dev-stop && make dev
29+
dev-new: build dev
30+
dev-restart: dev-stop dev
2431

25-
test:
26-
docker compose -f docker-compose.test.yml up -d --build
32+
# TEST
33+
test-start:
34+
docker compose ${TEST_FILE} up -d
35+
36+
test-build:
37+
docker compose ${TEST_FILE} build --no-cache
2738

2839
test-stop:
29-
docker compose -f docker-compose.test.yml down
40+
docker compose ${TEST_FILE} down
41+
42+
test: test-build test-start
43+
test-restart: test-stop test
3044

31-
test-restart:
32-
make test-stop && make test
45+
# UTILS
46+
dump-schema:
47+
docker exec ${DB_CONTAINER} pg_dump -U postgres -d ${DB_APP_DB_NAME} --schema-only > dump_schema
3348

34-
appdb-dump-schema:
35-
docker exec iss-main-db pg_dump -U postgres -d iss_app_db --schema-only > app_dump_schema
49+
dump-data:
50+
docker exec ${DB_CONTAINER} pg_dump -U postgres -d ${DB_APP_DB_NAME} --data-only > dump_data
3651

37-
appdb-dump-data:
38-
docker exec iss-main-db pg_dump -U postgres -d iss_app_db --data-only > app_dump_data
52+
dump-all: dump-schema dump-data
3953

40-
dump-database:
41-
make appdb-dump-schema && make appdb-dump-data
54+
init-admin:
55+
docker exec -it iss-back ./manage.py createsuperuser

README.md

Lines changed: 116 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,118 @@
1+
<img src="/docs/assets/preview.gif" alt="example">
2+
13
# ISS Data Collection Tool
24

3-
## Makefile convinient commands (**docker/docker-compose** and **.env file** are supposed to be set):
4-
5-
- start project:
6-
`make prod`
7-
- stop project:
8-
`make prod-stop`
9-
- restart project:
10-
`make prod-restart`
11-
- start project with rebuild:
12-
`make prod-new`
13-
- start development project:
14-
`make dev`
15-
- stop development project:
16-
`make dev-stop`
17-
- restart development project:
18-
`make dev-restart`
19-
- start project with rebuild:
20-
`make dev-new`
21-
- start tests:
22-
`make test`
23-
- stop tests:
24-
`make test-stop`
25-
- restart tests:
26-
`make test-restart`
27-
- dump main apps database schema:
28-
`make appdb-dump-schema`
29-
- dump main apps database data:
30-
`make appdb-dump-data`
31-
- dump main apps database (schema and data separately):
32-
`make dump-database`
33-
34-
## Prerequisites:
35-
36-
- **docker/docker-compose** installed
37-
- create and fill **.env** file from sample
38-
39-
For local development copying sample is enough:
40-
`cp .env.sample .env`
41-
42-
## Running Application
43-
44-
Docker Compose file: docker-compose.yml
45-
46-
Docker files:
47-
48-
- Dockerfile.backend
49-
- Dockerfile.frontend
50-
- Dockerfile.storage
51-
52-
Command:
53-
`docker-compose up -d --build`
54-
55-
## Development
56-
57-
Docker Compose file: docker-compose.dev.yml
58-
59-
Docker files:
60-
61-
- Dockerfile.backend
62-
- Dockerfile.frontend
63-
- Dockerfile.storage
64-
65-
Command:
66-
`docker-compose -f docker-compose.dev.yml up -d --build`
67-
68-
## Testing
69-
70-
Docker Compose file: docker-compose.test.yml
71-
72-
Docker files:
73-
74-
- Dockerfile.tests
75-
76-
Command (rebuild is important):
77-
`docker-compose -f docker-compose.test.yml up -d --build`
78-
79-
Available tests:
80-
81-
- Main Backend:
82-
`docker exec iss-test-back ./manage.py test`
83-
- Storage Backend:
84-
`docker exec iss-test-storage python3 src/test.py`
85-
- Frontend:
86-
`docker exec iss-test-front npm test`
87-
- Selenium Tests (browser emulation):
88-
`docker exec iss-tests python3 test.py`
89-
- Python linter (no output means the lint test is passed):
90-
`docker exec iss-tests flake8`
91-
- JavaScript linter:
92-
`docker exec iss-test-front npm run lint`
93-
- JavaScript ts compiler checker:
94-
`docker exec iss-test-front npm run compile`
5+
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.
6+
7+
🛠 Currently in active development. Ideal for internal use, pilots, and research-stage projects.
8+
9+
## 🧩 Features
10+
11+
This platform enables you to:
12+
13+
- Create projects with custom label systems
14+
- Upload images/videos and assign them to labeling schemas
15+
- validate uploaded files
16+
- Set collection goals
17+
- Track progress with stats
18+
- Export data
19+
20+
## 📚 Documentation & Examples
21+
22+
See [docs/](/docs) for manuals and walkthroughs:
23+
24+
- [Quickstart](/docs/quickstart.md)
25+
- [Projects](/docs/projects.md)
26+
- [Labels](/docs/labels.md)
27+
- [Users and Roles](/docs/users.md)
28+
- [Uploads](/docs/uploads.md)
29+
- [Validation](/docs/validation.md)
30+
- [Goals](/docs/goals.md)
31+
- [Statistics](/docs/statistics.md)
32+
- [Downloads](/docs/downloads.md)
33+
- [Annotation](/docs/annotation.md)
34+
35+
## ⚙️ Architecture
36+
37+
- **Main Backend:** Django + PostgreSQL
38+
- **File Backend:** FastAPI + MongoDB (blob storage)
39+
- **Task Queue:** Celery + Redis
40+
- **Frontend:** React
41+
- **Deployment:** Docker, Compose, Makefile-based workflow
42+
43+
## 📁 Folder Structure (Top Level)
44+
45+
- `backend-app/` — main Django app
46+
- `frontend-app/` — React app
47+
- `storage-app/` — FastAPI blob service
48+
- `scripts/` — app handy tools
49+
- `tests/` — global tests
50+
- `nginx/`, `redis/` — infrastructure configs
51+
- `Makefile` — common commands
52+
- `docker-compose*.yml` — dev/test/prod setup
53+
54+
## 🚀 Getting Started
55+
56+
### Prerequisites
57+
58+
- Docker + Docker Compose installed
59+
- `.env` file created from `.env.sample`
60+
61+
```bash
62+
cp .env.sample .env
63+
```
64+
65+
### Build & Run
66+
```bash
67+
make build # build all services
68+
make start # start in prod mode
69+
make dev # start in dev mode
70+
```
71+
Full command list available in the Makefile section below.
72+
73+
## 🧪 Testing
74+
Run with:
75+
```bash
76+
docker exec iss-test-back ./manage.py test # Main Backend
77+
docker exec iss-test-storage python3 src/test.py # Storage Backend
78+
docker exec iss-test-front npm test # Frontend
79+
docker exec iss-tests flake8 # Python linter
80+
docker exec iss-test-front npm run lint # JavaScript linter
81+
docker exec iss-test-front npm run compile # JavaScript ts compiler checker
82+
```
83+
84+
## 🛠️ Makefile Commands
85+
86+
General
87+
```bash
88+
make build # build all services
89+
make start # start in prod mode
90+
make stop # stop prod mode
91+
make start-new # rebuild and start services in prod mode
92+
make restart # stop and start in prod mode
93+
```
94+
95+
Dev Mode
96+
```bash
97+
make dev # start in dev mode
98+
make dev-stop # stop dev mode
99+
make dev-new # rebuild and start services in dev mode
100+
make dev-restart # stop and start in dev mode
101+
```
102+
103+
Tests
104+
```bash
105+
make test # rebuild and start services in test mode
106+
make test-start # start in test mode
107+
make test-build # build test mode
108+
make test-stop # stop test mode
109+
make test-restart # stop and start services in test mode
110+
```
111+
112+
Utils
113+
```bash
114+
make dump-schema # dump database schema
115+
make dump-data # dump database data
116+
make dump-all # dump database both schema and data
117+
make init-admin # create new superuser
118+
```

backend-app/archive/__init__.py

Whitespace-only changes.

backend-app/archive/apps.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class ArchiveConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'archive'

backend-app/archive/models.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from django.db.models import (
2+
Model,
3+
CharField,
4+
ForeignKey,
5+
ManyToManyField,
6+
DO_NOTHING,
7+
DateTimeField,
8+
BigIntegerField,
9+
JSONField,
10+
TextField
11+
)
12+
13+
14+
class Archive(Model):
15+
STATUSES = (("s", "SUCCESS"), ("f", "FAILURE"), ("p", "PENDING"),)
16+
17+
id = CharField(max_length=36, primary_key=True)
18+
result_id = CharField(max_length=24, null=True)
19+
result_size = BigIntegerField(null=True)
20+
result_message = TextField(null=True)
21+
status = CharField(max_length=1, choices=STATUSES, default="p")
22+
filters = JSONField()
23+
create_date = DateTimeField(auto_now_add=True)
24+
25+
project = ForeignKey("project.Project", on_delete=DO_NOTHING)
26+
author = ForeignKey("user.CustomUser", on_delete=DO_NOTHING)
27+
file = ManyToManyField("file.File")
28+
29+
class Meta:
30+
db_table = "archive"

backend-app/archive/permissions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from rest_framework.permissions import BasePermission
2+
from rest_framework.views import Request, APIView
3+
4+
5+
class ArchivesPermission(BasePermission):
6+
def has_permission(self, request: Request, view: APIView) -> bool | None:
7+
project_perm = bool(request.user.project_download.filter(id=view.kwargs["p_pk"]))
8+
return request.user.is_superuser or project_perm
9+
10+
11+
class ArchivePermission(BasePermission):
12+
def has_permission(self, request: Request, view: APIView) -> bool | None:
13+
project_perm = bool(request.user.project_download.filter(id=view.kwargs["p_pk"]))
14+
arch_perm = bool(request.user.archive_set.filter(id=view.kwargs["pk"]))
15+
return request.user.is_superuser or (project_perm and arch_perm)

backend-app/archive/serializers.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from rest_framework.serializers import ModelSerializer, ChoiceField, SerializerMethodField, IntegerField
2+
from .models import Archive
3+
4+
5+
class StatusChoiceField(ChoiceField):
6+
def to_representation(self, value: str) -> str: return self.choices[value]
7+
8+
9+
class ArchiveSerializer(ModelSerializer):
10+
status = StatusChoiceField(choices=Archive.STATUSES)
11+
author = SerializerMethodField()
12+
file_count = IntegerField()
13+
14+
class Meta:
15+
model = Archive
16+
exclude = ("file", "project")
17+
18+
def get_author(self, instance: Archive): return instance.author.username

0 commit comments

Comments
 (0)