Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
86685e4
Database schema
uxabix Oct 5, 2025
5928ebc
Models for accounts, chat and game apps
uxabix Oct 6, 2025
d1978b0
Helper methods for all objects, comments
uxabix Oct 7, 2025
89c1da9
Static files folder in settings.py, staticfiles url in urls.py, READM…
uxabix Oct 12, 2025
843874f
Models update
uxabix Oct 18, 2025
a80aae6
Admin panels for all apps
uxabix Oct 18, 2025
8019b06
Tests for models in all applications
uxabix Oct 19, 2025
24eb1f1
User Authentication and test for all scenarios
Viton8 Oct 21, 2025
1a2f7c1
Added some comments
Viton8 Oct 24, 2025
130b6ef
PR: requested changes
uxabix Oct 25, 2025
0c87313
Added generate_test_users command.
Surmachov Oct 25, 2025
1dc7906
Removed unnecessary comment line.
Surmachov Oct 25, 2025
8b9d816
Added __init__ in every managment/commands folder so pyhton whould un…
Surmachov Oct 26, 2025
b6d4f14
Major changes in tests
uxabix Oct 26, 2025
fddff33
CI setup
uxabix Oct 26, 2025
d341ec4
Update ci.yml
uxabix Oct 26, 2025
f3bd897
Merge pull request #4 from uxabix/feature/basic_models
Viton8 Oct 27, 2025
5861414
Added generate_test_users command.
Surmachov Oct 25, 2025
072d5cc
Removed unnecessary comment line.
Surmachov Oct 25, 2025
5e4e12d
Added __init__ in every managment/commands folder so pyhton whould un…
Surmachov Oct 26, 2025
d8a0c1c
Added backup* to .gitignore
Surmachov Oct 27, 2025
79709a8
Updated export_db.py
Surmachov Oct 27, 2025
8e1fcc9
Merge branch 'develop' into feature/registration
Viton8 Oct 28, 2025
113ff7b
Change test, to pytest
Viton8 Oct 29, 2025
db1ff80
Created init_game_data managment command
Surmachov Oct 30, 2025
11cfb76
Add base.html, and solve reviewed problems
Viton8 Oct 30, 2025
7982b00
unify comments across views, serializers, and tests
Viton8 Oct 31, 2025
a7be0ee
Refactor docstrings in authentication test cases
uxabix Oct 31, 2025
ffffcd5
fix wrong indentation in accounts/test_auth.py
Viton8 Oct 31, 2025
169d411
Merge pull request #7 from uxabix/feature/registration
uxabix Oct 31, 2025
ed7899a
Created generate_fake_games, reset_games and updated generate_test_us…
Surmachov Oct 31, 2025
6a6b0bd
Added generate_test_users command.
Surmachov Oct 25, 2025
2aea536
Removed unnecessary comment line.
Surmachov Oct 25, 2025
6311533
Added __init__ in every managment/commands folder so pyhton whould un…
Surmachov Oct 26, 2025
8be040c
Added backup* to .gitignore
Surmachov Oct 27, 2025
737efef
Added __init__ in every managment/commands folder so pyhton whould un…
Surmachov Oct 26, 2025
246a036
Created init_game_data managment command
Surmachov Oct 30, 2025
d6133f3
Created generate_fake_games, reset_games and updated generate_test_us…
Surmachov Oct 31, 2025
5004840
Merge remote-tracking branch 'origin/feature/managment_commands' into…
Surmachov Oct 31, 2025
9a6beb8
Added pytest for every management command.
Surmachov Oct 31, 2025
2b152f8
Fixes and refactoring of game management commands.
Surmachov Nov 4, 2025
a8bbcbd
Small adjustments of management commands.
Surmachov Nov 4, 2025
c7845d6
Small adjustments for generate_test_users management command.
Surmachov Nov 4, 2025
005f4ff
Merge pull request #10 from uxabix/feature/managment_commands
Viton8 Nov 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Django CI

on:
push:
branches: ["main", "master", "develop"]
pull_request:
branches: ["main", "master", "develop"]

jobs:
test:
runs-on: ubuntu-latest

services:
postgres:
image: postgres:15
env:
POSTGRES_DB: django_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready -U postgres"
--health-interval=5s
--health-timeout=5s
--health-retries=10

env:
DJANGO_SETTINGS_MODULE: Fools_Arena.settings
POSTGRES_DB: django_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
DATABASE_URL: postgres://postgres:postgres@localhost:5432/django_test
PYTHONPATH: .

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Wait for PostgreSQL to be ready
run: |
echo "Waiting for PostgreSQL to accept connections..."
for i in {1..10}; do
pg_isready -h localhost -p 5432 -U postgres && break
echo "PostgreSQL not ready yet, retrying in 3 seconds..."
sleep 3
done

- name: Run migrations
run: |
python manage.py migrate --noinput

- name: Run tests
run: |
pytest -v --disable-warnings
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ celerybeat.pid
*.sql.gz
*.dump
*.backup
backup*

# =========================
# Docker
Expand Down
Binary file added Docs/Database/dbschema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
210 changes: 210 additions & 0 deletions Docs/Database/dbschema.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
@startuml
' === LOOKUP TABLES ===

entity "CardSuit" as CardSuit {
*id : smallint
---
name : varchar
color : ENUM(red, black)
}

entity "CardRank" as CardRank {
*id : smallint
---
name : varchar
value : int
}

' === CORE ENTITIES ===

entity "User" as User {
*id : UUID
---
username : varchar
email : varchar
password_hash : varchar
avatar_url : varchar?
created_at : timestamp
}

entity "Lobby" as Lobby {
*id : UUID
---
name : varchar
owner_id : UUID [FK → User.id]
is_private : bool
password_hash : varchar?
status : ENUM(waiting, playing, closed)
created_at : timestamp
}

entity "LobbySettings" as LobbySettings {
*id : UUID
---
lobby_id : UUID [FK → Lobby.id]
max_players : int
card_count : ENUM(24, 36, 52)
is_transferable : bool
neighbor_throw_only : bool
allow_jokers : bool
turn_time_limit : int?
special_rule_set_id : UUID [FK → SpecialRuleSet.id]?
}

entity "LobbyPlayer" as LobbyPlayer {
*id : UUID
---
lobby_id : UUID [FK → Lobby.id]
user_id : UUID [FK → User.id]
status : ENUM(waiting, ready, playing, left)
}

entity "Game" as Game {
*id : UUID
---
lobby_id : UUID [FK → Lobby.id]
trump_card_id : UUID [FK → Card.id]
started_at : timestamp
finished_at : timestamp?
status : ENUM(in_progress, finished)
loser_id : UUID [FK → User.id]?
}

entity "GamePlayer" as GamePlayer {
*id : UUID
---
game_id : UUID [FK → Game.id]
user_id : UUID [FK → User.id]
seat_position : int
cards_remaining : int
}

entity "Card" as Card {
*id : UUID
---
suit_id : smallint [FK → CardSuit.id]
rank_id : smallint [FK → CardRank.id]
special_card_id : UUID? [FK → SpecialCard.id]
}

' === CARD STATES ===

entity "GameDeck" as GameDeck {
*id : UUID
---
game_id : UUID [FK → Game.id]
card_id : UUID [FK → Card.id]
position : int
}

entity "PlayerHand" as PlayerHand {
*id : UUID
---
game_id : UUID [FK → Game.id]
player_id : UUID [FK → User.id]
card_id : UUID [FK → Card.id]
order_in_hand : int?
}

entity "TableCard" as TableCard {
*id : UUID
---
game_id : UUID [FK → Game.id]
attack_card_id : UUID [FK → Card.id]
defense_card_id : UUID? [FK → Card.id]
}

entity "DiscardPile" as DiscardPile {
*id : UUID
---
game_id : UUID [FK → Game.id]
card_id : UUID [FK → Card.id]
position : int?
}

' === RULES ===

entity "SpecialRuleSet" as SpecialRuleSet {
*id : UUID
---
name : varchar
description : text?
min_players : int
}

entity "SpecialCard" as SpecialCard {
*id : UUID
---
name : varchar
effect_type : ENUM(skip, reverse, draw, custom)
effect_value : jsonb?
description : text?
}

entity "SpecialRuleSetCard" as SpecialRuleSetCard {
*id : UUID
---
rule_set_id : UUID [FK → SpecialRuleSet.id]
card_id : UUID [FK → SpecialCard.id]
}

' === GAME FLOW ===

entity "Turn" as Turn {
*id : UUID
---
game_id : UUID [FK → Game.id]
player_id : UUID [FK → User.id]
turn_number : int
}

entity "Move" as Move {
*id : UUID
---
turn_id : UUID [FK → Turn.id]
table_card_id : UUID [FK → TableCard.id]
action_type : ENUM(attack, defend, pickup)
created_at : timestamp
}

entity "Message" as Message {
*id : UUID
---
sender_id : UUID [FK → User.id]
receiver_id : UUID? [FK → User.id]
lobby_id : UUID? [FK → Lobby.id]
content : text
sent_at : timestamp
}

' === RELATIONSHIPS ===

User ||--o{ Lobby
User ||--o{ LobbyPlayer
User ||--o{ Message
User ||--o{ GamePlayer
Lobby ||--|| LobbySettings
Lobby ||--o{ LobbyPlayer
Lobby ||--o{ Game
Lobby ||--o{ Message
Game ||--o{ GamePlayer
Game ||--o{ Turn
Game ||--|| Card : trump >
Game ||--o{ GameDeck
Game ||--o{ PlayerHand
Game ||--o{ TableCard
Game ||--o{ DiscardPile
Game ||--|| User : loser >
Turn ||--o{ Move
TableCard ||--o{ Move
CardSuit ||--o{ Card
CardRank ||--o{ Card
Card ||--o{ GameDeck
Card ||--o{ PlayerHand
Card ||--o{ TableCard
Card ||--o{ DiscardPile
SpecialRuleSet ||--o{ LobbySettings
SpecialRuleSet ||--o{ SpecialRuleSetCard
SpecialCard ||--o{ SpecialRuleSetCard
SpecialCard ||--o{ Card
@enduml
1 change: 1 addition & 0 deletions Docs/Database/dbschema.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Docs/Models.png
Binary file not shown.
4 changes: 3 additions & 1 deletion Fools_Arena/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

# WebSockets
INSTALLED_APPS += ['channels']
ASGI_APPLICATION = 'myproject.asgi.application'
ASGI_APPLICATION = 'Fools_Arena.asgi.application'

CHANNEL_LAYERS = {
"default": {
Expand Down Expand Up @@ -119,6 +119,7 @@
},
]

AUTH_USER_MODEL = 'accounts.User'

# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
Expand All @@ -136,6 +137,7 @@
# https://docs.djangoproject.com/en/5.2/howto/static-files/

STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / 'staticfiles'

# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
Expand Down
16 changes: 15 additions & 1 deletion Fools_Arena/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,22 @@
"""

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import path, include

urlpatterns = [
path("admin/", admin.site.urls),
# UI
path('accounts/', include('accounts.urls')),

# API
path('api/accounts/', include('accounts.api_urls')),

]

# Add static files
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,32 @@ Available services:
- Django + Channels: http://localhost:8000
- PostgreSQL: localhost:5432

### 4. Apply migrations and create superuser
### 4. Apply migrations and create a superuser
Run migrations:
```bash
docker-compose exec web python manage.py migrate
docker compose exec web python manage.py migrate
```
Create a superuser (optional):
```bash
docker-compose exec web python manage.py createsuperuser
docker compose exec web python manage.py createsuperuser
```

### 5. Generate static files
```bash
docker compose exec web python manage.py collectstatic
```

### 5. Work with Django
### 6. Work with Django
All commands should be executed inside the web container. Examples:
```bash
docker-compose exec web python manage.py shell
docker-compose exec web python manage.py makemigrations
docker-compose exec web python manage.py test
docker compose exec web python manage.py shell
docker compose exec web python manage.py makemigrations
docker compose exec web pytest -v
```

### 6. Stop containers
### 7. Stop containers
```bash
docker-compose down
docker compose down
```
---

Expand All @@ -59,7 +63,7 @@ docker-compose down

## 📌 Status
Early development stage.
See [ROADMAP.md](./ROADMAP.md) for roadmap.
See [ROADMAP.md](./ROADMAP.md) for the roadmap.

---

Expand Down
Loading