Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 43 additions & 0 deletions .idea/copilotDiffState.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 149 additions & 0 deletions doc/firebase-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Configuración Firebase para InazumaGo

## Estado Actual
- ✅ Repositorio HTTP en OkHttp (FirebaseMainRepository) implementado
- ✅ AuthService mock para desarrollo
- ✅ Tests básicos pasando (sin dependencia de Firebase real)
- ⏳ **Falta: Configurar Firebase Console**

---

## Pasos para Configurar Firebase (10-15 min)

### 1. Crear Proyecto en Firebase Console
1. Ve a **https://console.firebase.google.com**
2. Click **"Crear proyecto"**
3. Nombre: `InazumaGo`
4. Deshabilita Analytics (por ahora, opcional)
5. Click **"Crear"**

### 2. Habilitar Realtime Database
1. En el proyecto, ve a **"Realtime Database"** (en el menú lateral)
2. Click **"Crear base de datos"**
3. Ubicación: **Europe (europe-west1)** o **us-central1**
4. Modo: **Start in test mode** (por ahora, abierta para desarrollo)
5. Click **"Crear"**

Firebase generará una URL como:
```
https://inazumago-abc123.firebaseio.com
```

### 3. Copiar URL a `application.properties`

**Archivo:** `src/main/resources/application.properties`

```properties
# Firebase URL (sin .json)
firebase.url=https://inazumago-abc123.firebaseio.com
firebase.timeout.seconds=30
firebase.auth.token=
```

### 4. (Alternativa) Usar Variable de Entorno

```powershell
# PowerShell
$env:FIREBASE_URL="https://inazumago-abc123.firebaseio.com"
```

O en `.env`:
```
FIREBASE_URL=https://inazumago-abc123.firebaseio.com
FIREBASE_AUTH_TOKEN=
```

### 5. Reglas de Seguridad RTDB (Desarrollo)

**Para DESARROLLO:** En Firebase Console → Realtime Database → Rules

```json
{
"rules": {
".read": true,
".write": true,
"games": {
"$gameId": {
".validate": "newData.hasChild('players')",
"players": {
".validate": "newData.val().length() <= 2"
},
"moves": {
".validate": "!data.exists() || newData.val().length() >= data.val().length()"
}
}
}
}
}
```

**Para PRODUCCIÓN:** (después, con autenticación real)

```json
{
"rules": {
".read": "auth != null",
".write": "auth != null",
"games": {
"$gameId": {
".validate": "newData.hasChildren(['id', 'players', 'status'])",
"players": {
".validate": "newData.val().length() >= 2 && newData.val().length() <= 2"
},
"moves": {
".validate": "root.child('games').child($gameId).child('currentTurn') != null"
}
}
}
}
}
```

---

## Testing con Firebase Real

**Una vez configurado, Red puede hacer:**

1. Tests WireMock (ya listos en `FirebaseMainRepositoryTest`)
2. Tests contra Firebase real (descomenta tras configurar):

```java
@Test
void testCreateGameAgainstFirebase() throws Exception {
GameDto game = new GameDto("game-real-123", "Test",
Arrays.asList("p1", "p2"), "IN_PROGRESS", System.currentTimeMillis());

FirebaseMainRepository repo = new FirebaseMainRepository(
System.getenv("FIREBASE_URL")
);
CompletableFuture<GameDto> result = repo.createGame(game);
GameDto created = result.get();

assertNotNull(created);
assertEquals("game-real-123", created.getId());
}
```

---

## Checklist para Red

- [ ] Firebase Console: Proyecto creado
- [ ] RTDB: Base de datos creada (EU o US)
- [ ] RTDB URL: Copiada a `application.properties`
- [ ] Reglas: Aplicadas (desarrollo first)
- [ ] Tests: Ejecutados contra Firebase real (opcional ahora, hacer después)

---

## Próximo Paso (E2-US3)

Cuando Firebase esté configurado, Red implementa:
- AuthService real (Firebase Authentication)
- Integración de tokens en peticiones
- SSE o WebSocket para listeners en tiempo real

**Responsable:** Red Team
**Estimación:** 1-2 sprints
**Bloqueador:** Firebase configurado
165 changes: 165 additions & 0 deletions doc/game-implementation-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Guía para Implementar una Partida Jugable (Motor + UI)

## Estado Actual de Red
✅ FirebaseMainRepository (cliente HTTP OkHttp)
✅ AuthService (mock para desarrollo)
✅ 34 tests pasando

---

## Lo que Motor Necesita Hacer

### 1. **Sincronización Optimistic + Rollback** (E2-US4-T3)
Crear en `GameService`:
```java
public CompletableFuture<Void> executeMove(String gameId, MoveData move) {
// 1. Aplicar movimiento localmente (optimistic)
localGame.getMoves().add(move);

// 2. Enviar a Firebase
MovePayload payload = new MovePayload(Arrays.asList(move), System.currentTimeMillis());
return mainRepository.writeMoveMultiPath(gameId, payload)
.exceptionally(e -> {
// 3. Rollback si falla (403, timeout, etc.)
localGame.getMoves().remove(move);
throw new RuntimeException("Movimiento rechazado: " + e.getMessage());
});
}
```

### 2. **Reglas de Validación de Movimientos** (E3-US2)
Crear interfaz `MoveValidator`:
```java
public interface MoveValidator {
void validateMove(Game game, MoveData move) throws InvalidMoveException;
}
```

Implementación:
```java
public class InazumaGoMoveValidator implements MoveValidator {
@Override
public void validateMove(Game game, MoveData move) throws InvalidMoveException {
// Validar: turno, posición, acción permitida, etc.
if (!isPlayerTurn(game, move.getPlayerId())) {
throw new InvalidMoveException("No es tu turno");
}
if (!isValidPosition(move.getPosition())) {
throw new InvalidMoveException("Posición fuera del campo");
}
}
}
```

### 3. **Integración en GameService**
```java
public CompletableFuture<Void> executeMove(String gameId, MoveData move) {
return CompletableFuture.runAsync(() -> {
try {
moveValidator.validateMove(currentGame, move);
// Enviar a Firebase...
mainRepository.writeMoveMultiPath(gameId, ...);
currentGame.nextTurn(); // Cambiar turno
} catch (InvalidMoveException e) {
throw new RuntimeException(e);
}
});
}
```

---

## Lo que UI Necesita Hacer

### 1. **Pantalla de Partida**
Crear `GameController.fxml` + `GameController.java`:
```java
@FXML private Label playerNameLabel;
@FXML private Button kickButton, passButton;
@FXML private Canvas gameCanvas; // Dibujar campo

private GameService gameService;
private String currentGameId;

@FXML private void onKickPressed() {
MoveData move = new MoveData(playerName, "KICK", selectedPosition);
gameService.executeMove(currentGameId, move)
.exceptionally(e -> {
showError("Movimiento rechazado: " + e.getMessage());
return null;
});
}
```

### 2. **Listeners en Tiempo Real**
```java
private void subscribeToMoves(String gameId) {
String listenerId = gameService.addMovesListener(gameId, moves -> {
// Actualizar UI con nuevos movimientos
Platform.runLater(() -> renderMoves(moves));
});
}
```

### 3. **Flujo de Creación de Partida**
```
1. Pantalla de login (usa AuthService)
2. Pantalla de lobby (listar partidas o crear nueva)
3. Pantalla de espera (esperando segundo jugador)
4. Pantalla de partida (turnos, movimientos)
5. Pantalla de resultado (victoria/derrota/abandono)
```

---

## Para que Compile Todo Junto

Motor debe crear:
- [ ] `MoveValidator` interface + `InazumaGoMoveValidator`
- [ ] Método `executeMove()` en `GameService`
- [ ] Tests de `MoveValidator` (qué movimientos son válidos)

UI debe crear:
- [ ] `GameController.fxml` (diseño básico del campo)
- [ ] `GameController.java` (wiring con GameService)
- [ ] `AuthenticationController.fxml` + `.java` (login mock)
- [ ] Actualizar `MainGUI.java` para cargar `AuthenticationController` primero

---

## Orden de Implementación (Rápido)

**Día 1 - Motor:**
1. `MoveValidator` interface
2. `InazumaGoMoveValidator` (validar turno, posición)
3. `executeMove()` en `GameService` (con optimistic update + rollback)

**Día 1 - UI:**
1. `AuthenticationController` (login mock, reutiliza `AuthServiceImpl`)
2. `GameController.fxml` (canvas con campo + botones)

**Día 2 - Integración:**
1. Flujo completo: login → crear partida → jugar
2. Sync de movimientos (listeners)
3. Tests E2E con stubs

---

## Firebase (Red) - Paralelo
Mientras Motor y UI trabajan:
1. Configura Firebase Console (10 min)
2. Copia URL a `application.properties`
3. Escribe reglas RTDB

**No hace falta esperar a nada - Red ya dejó el código listo.**

---

## Checklist Final

- [ ] Motor: `MoveValidator` + `executeMove()`
- [ ] UI: `AuthenticationController` + `GameController`
- [ ] Tests: Mínimo 3 tests de validación de movimientos
- [ ] Firebase: Configurado en Console
- [ ] Partida: Crear, jugar 2 turnos mínimo, ver resultado

Loading
Loading