Add initial implementations for result types and user events - #4
Conversation
…, teams, tokens, upload logs, and user events
There was a problem hiding this comment.
Pull request overview
This PR expands the Django project’s domain coverage by introducing a set of new “unmanaged” apps/models (to map existing DB tables) plus consistent Django admin handling for timestamp fields, and wires these apps into the base environment settings.
Changes:
- Added multiple new Django apps (models + admin + app scaffolding) for events/structure/results/admin domains (e.g., classes, clubs, splits, tokens, etc.).
- Introduced a reusable
TimestampedModelAdminand applied it across the new (and updated) admin registrations. - Updated settings/dependencies and local Docker compose configuration (custom user model setting + bcrypt dependency + compose env/network changes).
Reviewed changes
Copilot reviewed 74 out of 137 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| Pipfile | Add bcrypt dependency |
| oreplay/environments/base.py | Set AUTH_USER_MODEL, expand INSTALLED_APPS |
| docker-compose-python.yaml | Use .env; adjust external network name |
| apps/admin_base.py | Add TimestampedModelAdmin base admin |
| apps/shared_models.py | Add BaseUnmanagedModel + verbose-name normalization |
| .gitignore | Add negated patterns for apps/* |
| apps/usersevents/urls.py | App URL scaffold (empty) |
| apps/usersevents/tests.py | Test scaffold placeholder |
| apps/usersevents/models.py | Add unmanaged UsersEvents model |
| apps/usersevents/migrations/init.py | Migration package scaffold |
| apps/usersevents/apps.py | AppConfig scaffold |
| apps/usersevents/admin.py | Admin registration for UsersEvents |
| apps/usersevents/views.py | Views scaffold placeholder |
| apps/usersevents/init.py | Package scaffold |
| apps/users/models.py | Custom User manager/auth helpers + bcrypt check |
| apps/users/apps.py | Call unmanaged model name normalizer in ready() |
| apps/users/admin.py | Register User/AccessToken with timestamped admin |
| apps/uploadlogs/urls.py | App URL scaffold (empty) |
| apps/uploadlogs/tests.py | Test scaffold placeholder |
| apps/uploadlogs/models.py | Add unmanaged UploadLogs model |
| apps/uploadlogs/migrations/init.py | Migration package scaffold |
| apps/uploadlogs/apps.py | AppConfig scaffold |
| apps/uploadlogs/admin.py | Admin registration for UploadLogs |
| apps/uploadlogs/views.py | Views scaffold placeholder |
| apps/uploadlogs/init.py | Package scaffold |
| apps/tokens/urls.py | App URL scaffold (empty) |
| apps/tokens/tests.py | Test scaffold placeholder |
| apps/tokens/models.py | Add unmanaged Tokens model |
| apps/tokens/migrations/init.py | Migration package scaffold |
| apps/tokens/apps.py | AppConfig scaffold |
| apps/tokens/admin.py | Admin registration for Tokens |
| apps/tokens/views.py | Views scaffold placeholder |
| apps/tokens/init.py | Package scaffold |
| apps/teams/urls.py | App URL scaffold (empty) |
| apps/teams/tests.py | Test scaffold placeholder |
| apps/teams/models.py | Add unmanaged Teams + TeamResults models |
| apps/teams/migrations/init.py | Migration package scaffold |
| apps/teams/apps.py | AppConfig scaffold |
| apps/teams/admin.py | Admin registrations for teams/results |
| apps/teams/views.py | Views scaffold placeholder |
| apps/teams/init.py | Package scaffold |
| apps/stages/urls.py | App URL scaffold (empty) |
| apps/stages/tests.py | Test scaffold placeholder |
| apps/stages/models.py | Add unmanaged stage-related models |
| apps/stages/migrations/init.py | Migration package scaffold |
| apps/stages/apps.py | AppConfig scaffold |
| apps/stages/admin.py | Admin registrations for stage models |
| apps/stages/views.py | Views scaffold placeholder |
| apps/stages/init.py | Package scaffold |
| apps/splits/urls.py | App URL scaffold (empty) |
| apps/splits/tests.py | Test scaffold placeholder |
| apps/splits/models.py | Add unmanaged Splits model |
| apps/splits/migrations/init.py | Migration package scaffold |
| apps/splits/apps.py | AppConfig scaffold |
| apps/splits/admin.py | Admin registration for Splits |
| apps/splits/views.py | Views scaffold placeholder |
| apps/splits/init.py | Package scaffold |
| apps/runners/urls.py | App URL scaffold (empty) |
| apps/runners/tests.py | Test scaffold placeholder |
| apps/runners/models.py | Add unmanaged runners + results models |
| apps/runners/migrations/init.py | Migration package scaffold |
| apps/runners/apps.py | AppConfig scaffold |
| apps/runners/admin.py | Admin registrations for runners/results |
| apps/runners/views.py | Views scaffold placeholder |
| apps/runners/init.py | Package scaffold |
| apps/resulttypes/urls.py | App URL scaffold (empty) |
| apps/resulttypes/tests.py | Test scaffold placeholder |
| apps/resulttypes/models.py | Add unmanaged ResultTypes model |
| apps/resulttypes/migrations/init.py | Migration package scaffold |
| apps/resulttypes/apps.py | AppConfig scaffold |
| apps/resulttypes/admin.py | Admin registration for ResultTypes |
| apps/resulttypes/views.py | Views scaffold placeholder |
| apps/resulttypes/init.py | Package scaffold |
| apps/rawuploads/urls.py | App URL scaffold (empty) |
| apps/rawuploads/tests.py | Test scaffold placeholder |
| apps/rawuploads/models.py | Add unmanaged RawUploads model |
| apps/rawuploads/migrations/init.py | Migration package scaffold |
| apps/rawuploads/apps.py | AppConfig scaffold |
| apps/rawuploads/admin.py | Admin registration for RawUploads |
| apps/rawuploads/views.py | Views scaffold placeholder |
| apps/rawuploads/init.py | Package scaffold |
| apps/rankings/views.py | Views scaffold placeholder |
| apps/rankings/urls.py | App URL scaffold (empty) |
| apps/rankings/tests.py | Test scaffold placeholder |
| apps/rankings/models.py | Add unmanaged Ranking model |
| apps/rankings/migrations/init.py | Migration package scaffold |
| apps/rankings/apps.py | AppConfig scaffold |
| apps/rankings/admin.py | Admin registration for Ranking |
| apps/rankings/init.py | Package scaffold |
| apps/federations/urls.py | App URL scaffold (empty) |
| apps/federations/tests.py | Test scaffold placeholder |
| apps/federations/models.py | Add unmanaged Federations model |
| apps/federations/migrations/init.py | Migration package scaffold |
| apps/federations/apps.py | AppConfig scaffold |
| apps/federations/admin.py | Admin registration for Federations |
| apps/federations/views.py | Views scaffold placeholder |
| apps/federations/init.py | Package scaffold |
| apps/events/urls.py | App URL scaffold (empty) |
| apps/events/tests.py | Test scaffold placeholder |
| apps/events/models.py | Add unmanaged Events model |
| apps/events/migrations/init.py | Migration package scaffold |
| apps/events/apps.py | AppConfig scaffold |
| apps/events/admin.py | Admin registration for Events |
| apps/events/views.py | Views scaffold placeholder |
| apps/events/init.py | Package scaffold |
| apps/courses/urls.py | App URL scaffold (empty) |
| apps/courses/tests.py | Test scaffold placeholder |
| apps/courses/models.py | Add unmanaged Courses model |
| apps/courses/migrations/init.py | Migration package scaffold |
| apps/courses/apps.py | AppConfig scaffold |
| apps/courses/admin.py | Admin registration for Courses |
| apps/courses/views.py | Views scaffold placeholder |
| apps/courses/init.py | Package scaffold |
| apps/controls/urls.py | App URL scaffold (empty) |
| apps/controls/tests.py | Test scaffold placeholder |
| apps/controls/models.py | Add unmanaged controls-related models |
| apps/controls/migrations/init.py | Migration package scaffold |
| apps/controls/apps.py | AppConfig scaffold |
| apps/controls/admin.py | Admin registrations for controls models |
| apps/controls/views.py | Views scaffold placeholder |
| apps/controls/init.py | Package scaffold |
| apps/clubs/urls.py | App URL scaffold (empty) |
| apps/clubs/tests.py | Test scaffold placeholder |
| apps/clubs/models.py | Add unmanaged Clubs model |
| apps/clubs/migrations/init.py | Migration package scaffold |
| apps/clubs/apps.py | AppConfig scaffold |
| apps/clubs/admin.py | Admin registration for Clubs |
| apps/clubs/views.py | Views scaffold placeholder |
| apps/clubs/init.py | Package scaffold |
| apps/classes/urls.py | App URL scaffold (empty) |
| apps/classes/tests.py | Test scaffold placeholder |
| apps/classes/models.py | Add unmanaged classes-related models |
| apps/classes/migrations/init.py | Migration package scaffold |
| apps/classes/apps.py | AppConfig scaffold |
| apps/classes/admin.py | Admin registrations for classes models |
| apps/classes/views.py | Views scaffold placeholder |
| apps/classes/init.py | Package scaffold |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "runner_result", | ||
| "team_result", | ||
| "class_", | ||
| "control", | ||
| ] |
| "reading_time", | ||
| "created", | ||
| ] | ||
| search_fields = ["sicard", "station"] |
| list_display = ["id", "event", "stage", "station", "control_type", "created"] | ||
| search_fields = ["station"] | ||
| list_filter = ["event", "stage", "control_type"] |
| "created", | ||
| ] | ||
| search_fields = ["order_number"] | ||
| list_filter = ["event", "stage", "order_number"] |
| list_display = ["user", "event", "created"] | ||
| search_fields = ["user__username", "event__description"] | ||
| list_filter = ["event"] |
| env_file: | ||
| - .env.example | ||
| - .env | ||
| extra_hosts: |
…ry_class' for consistency across classes, runners, splits, teams, and rankings. Add scoring_algorithm field to Ranking model.
There was a problem hiding this comment.
Pull request overview
This PR expands the project’s domain model by introducing a shared unmanaged-model foundation plus a reusable Django admin base for timestamp handling, and then scaffolds a large set of new “read-only/unmanaged” apps (events/structure/results/admin-related entities). It also switches the project to a custom users.User auth model and adds bcrypt for legacy password verification.
Changes:
- Add
TimestampedModelAdminandBaseUnmanagedModel/naming normalization helpers to standardize admin + unmanaged model behavior. - Introduce many new Django apps with unmanaged models + admin registrations (events, stages, courses, controls, classes, clubs, teams, runners, splits, tokens, uploadlogs, rawuploads, rankings, user-event links, etc.).
- Configure
AUTH_USER_MODELand enhanceusers.Userwith a custom manager and bcrypt-compatible password checking.
Reviewed changes
Copilot reviewed 74 out of 137 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Pipfile | Adds bcrypt dependency (lockfile update needed). |
| oreplay/environments/base.py | Sets AUTH_USER_MODEL and expands/reorders INSTALLED_APPS. |
| docker-compose-python.yaml | Uses .env for env_file and renames the external network. |
| .gitignore | Adds explicit tracking exceptions for new apps/* modules. |
| apps/admin_base.py | Introduces TimestampedModelAdmin for consistent timestamp fields behavior in Django admin. |
| apps/shared_models.py | Adds BaseUnmanagedModel (+ stage-scoped base) and verbose-name normalization for unmanaged models. |
| apps/users/models.py | Implements UserManager, adds bcrypt-aware check_password, and auth-related properties on User. |
| apps/users/apps.py | Calls unmanaged model verbose-name normalization at app startup. |
| apps/users/admin.py | Registers User and AccessToken using TimestampedModelAdmin. |
| apps/classes/urls.py | Adds empty URLConf scaffold for classes. |
| apps/classes/models.py | Adds unmanaged Classes and ClassesControls models. |
| apps/classes/apps.py | Adds app config for classes. |
| apps/classes/admin.py | Registers Classes and ClassesControls in admin. |
| apps/clubs/urls.py | Adds empty URLConf scaffold for clubs. |
| apps/clubs/models.py | Adds unmanaged Clubs model. |
| apps/clubs/apps.py | Adds app config for clubs. |
| apps/clubs/admin.py | Registers Clubs in admin. |
| apps/controls/urls.py | Adds empty URLConf scaffold for controls. |
| apps/controls/models.py | Adds unmanaged Controls and ControlTypes models. |
| apps/controls/apps.py | Adds app config for controls. |
| apps/controls/admin.py | Registers Controls/ControlTypes in admin using shared timestamp admin. |
| apps/courses/urls.py | Adds empty URLConf scaffold for courses. |
| apps/courses/models.py | Adds unmanaged Courses model. |
| apps/courses/apps.py | Adds app config for courses. |
| apps/courses/admin.py | Registers Courses in admin. |
| apps/events/urls.py | Adds empty URLConf scaffold for events. |
| apps/events/models.py | Adds unmanaged Events model. |
| apps/events/apps.py | Adds app config for events. |
| apps/events/admin.py | Registers Events in admin. |
| apps/federations/urls.py | Adds empty URLConf scaffold for federations. |
| apps/federations/models.py | Adds unmanaged Federations model. |
| apps/federations/apps.py | Adds app config for federations. |
| apps/federations/admin.py | Registers Federations in admin. |
| apps/stages/urls.py | Adds empty URLConf scaffold for stages. |
| apps/stages/models.py | Adds unmanaged Stages, StageTypes, StageOrders models. |
| apps/stages/apps.py | Adds app config for stages. |
| apps/stages/admin.py | Registers stage models in admin. |
| apps/teams/urls.py | Adds empty URLConf scaffold for teams. |
| apps/teams/models.py | Adds unmanaged Teams and TeamResults models. |
| apps/teams/apps.py | Adds app config for teams. |
| apps/teams/admin.py | Registers team models in admin. |
| apps/runners/urls.py | Adds empty URLConf scaffold for runners. |
| apps/runners/models.py | Adds unmanaged Runners and RunnerResults models. |
| apps/runners/apps.py | Adds app config for runners. |
| apps/runners/admin.py | Registers runner models in admin. |
| apps/resulttypes/urls.py | Adds empty URLConf scaffold for resulttypes. |
| apps/resulttypes/models.py | Adds unmanaged ResultTypes model. |
| apps/resulttypes/apps.py | Adds app config for resulttypes. |
| apps/resulttypes/admin.py | Registers ResultTypes in admin. |
| apps/splits/urls.py | Adds empty URLConf scaffold for splits. |
| apps/splits/models.py | Adds unmanaged Splits model. |
| apps/splits/apps.py | Adds app config for splits. |
| apps/splits/admin.py | Registers Splits in admin. |
| apps/tokens/urls.py | Adds empty URLConf scaffold for tokens. |
| apps/tokens/models.py | Adds unmanaged Tokens model. |
| apps/tokens/apps.py | Adds app config for tokens. |
| apps/tokens/admin.py | Registers Tokens in admin. |
| apps/uploadlogs/urls.py | Adds empty URLConf scaffold for uploadlogs. |
| apps/uploadlogs/models.py | Adds unmanaged UploadLogs model. |
| apps/uploadlogs/apps.py | Adds app config for uploadlogs. |
| apps/uploadlogs/admin.py | Registers UploadLogs in admin. |
| apps/rawuploads/urls.py | Adds empty URLConf scaffold for rawuploads. |
| apps/rawuploads/models.py | Adds unmanaged RawUploads model. |
| apps/rawuploads/apps.py | Adds app config for rawuploads. |
| apps/rawuploads/admin.py | Registers RawUploads in admin. |
| apps/rankings/views.py | Adds placeholder views module for rankings. |
| apps/rankings/urls.py | Adds empty URLConf scaffold for rankings. |
| apps/rankings/tests.py | Adds placeholder tests module for rankings. |
| apps/rankings/models.py | Adds unmanaged Ranking model. |
| apps/rankings/apps.py | Adds app config for rankings. |
| apps/rankings/admin.py | Registers Ranking in admin. |
| apps/usersevents/urls.py | Adds empty URLConf scaffold for usersevents. |
| apps/usersevents/models.py | Adds unmanaged UsersEvents join model. |
| apps/usersevents/apps.py | Adds app config for usersevents. |
| apps/usersevents/admin.py | Registers UsersEvents in admin. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| django-cors-headers = "==4.9.0" # Manejo de CORS (actualizado) | ||
| drf-spectacular = "*" | ||
| bcrypt = "*" | ||
| setuptools = "==82.0.1" |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in commit 5bd3dac. Regenerated Pipfile.lock — bcrypt is now included in the default section with pinned hashes for consistent installs.
| class UsersEventsAdmin(TimestampedModelAdmin): | ||
| list_display = ["user", "event", "created"] | ||
| search_fields = ["user__username", "event__description"] | ||
| list_filter = ["event"] |
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Fixed in commit 588fc8c. Changed user__username to user__email in search_fields since username is only a Python @property on the User model (not a database field), which would cause a FieldError in admin search.
| def create_user(self, email, password=None, **extra_fields): | ||
| if not email: | ||
| raise ValueError("The email field is required") | ||
| email = self.normalize_email(email) | ||
| user = self.model(email=email, **extra_fields) | ||
| if password: | ||
| user.set_password(password) | ||
| user.save(using=self._db) | ||
| return user |
…r__username Agent-Logs-Url: https://github.com/oreplay/oreplay-python/sessions/5fa3f944-e8f8-47f1-b5ed-5cb5e94c671d Co-authored-by: udernaeb <118601411+udernaeb@users.noreply.github.com>
Agent-Logs-Url: https://github.com/oreplay/oreplay-python/sessions/1cc3ce7f-3337-4801-8119-5885bee6f496 Co-authored-by: udernaeb <118601411+udernaeb@users.noreply.github.com>
|



This pull request introduces two new Django apps,
classesandclubs, along with their models, admin interfaces, and configuration. It also adds a reusableTimestampedModelAdminbase class for consistent handling of timestamp fields in the Django admin, and integrates this base admin into the new and existing apps. Additionally, thebcryptpackage is added to the dependencies.New app and model implementations:
Classes App:
apps/classesapp with configuration (apps.py), empty URL routing (urls.py), and two models:ClassesandClassesControls, both inheriting fromBaseUnmanagedModel. The models include foreign keys to related entities and custom string representations. ([[1]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-1069263258a3876f3e3489cef17022e73c57419de816358750d4b0fe9c913a8cR1-R6),[[2]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-78b7096c0805430dcd1bd3c4deaf618843288c71628f468d8f8cb09d42ca6840R1-R5),[[3]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-eba775b94ad6ed660c5dc8c19f4813c2a01ed43e0f79fee27ba05917d6db5f9eR1-R85))TimestampedModelAdmin, with customized display, search, and filter options. ([apps/classes/admin.pyR1-R43](https://github.com/oreplay/oreplay-python/pull/4/files#diff-8190b95abe3dc6fa4a21eab05b55e5f431b9e513b1b1c45e01446e1166ea2363R1-R43))Clubs App:
apps/clubsapp with configuration (apps.py), empty URL routing (urls.py), and aClubsmodel with foreign keys and custom string representation. ([[1]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-a7971a1ddd29c234966bcd4eecfbae7dda41c54e249ecefc8503965b4f39e82aR1-R6),[[2]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-7d6ab8780deefa111aa7defea6123e76df18177dac8bad308b27681583a0508cR1-R5),[[3]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-05d43b6fa289db89bdc080c7a86eddca0e8de36111cdfda204a9659c9d897de9R1-R30))Clubsmodel in the Django admin usingTimestampedModelAdmin, with customized list and filter options. ([apps/clubs/admin.pyR1-R23](https://github.com/oreplay/oreplay-python/pull/4/files#diff-7717250e234151128d922a2de0b241777c0ed3666fdcf1f466a723f4bacbad5bR1-R23))Reusable admin improvements:
TimestampedModelAdmininapps/admin_base.py, a reusable base class for Django admin that automatically handlescreated,modified, anddeletedfields as read-only and updates them appropriately on save and delete actions. This centralizes timestamp management for all models using this admin class. ([apps/admin_base.pyR1-R61](https://github.com/oreplay/oreplay-python/pull/4/files#diff-339f5750bf082a779854056bc3a8354e818d8737326baed13b4f69ea20b98b70R1-R61))Other improvements:
apps/controls/admin.pyto useTimestampedModelAdminforControlsandControlTypesmodels, ensuring consistent timestamp handling and admin interface improvements. ([apps/controls/admin.pyR1-R24](https://github.com/oreplay/oreplay-python/pull/4/files#diff-718b8bbb17cdd3e0f48ad6fc187492527da01906bebcae824ad620d2e21d64d7R1-R24))Dependency updates:
bcryptdependency, likely for password hashing or security enhancements. ([PipfileR16](https://github.com/oreplay/oreplay-python/pull/4/files#diff-230078d672f10d17463a8a6265cad825b790885898256a3365be90685caac58dR16))