test: add full-stack Playwright integration test infrastructure
Sprint 12 Phase 2: Real integration tests with seed DB - R__seed_test_data.sql (Flyway repeatable, 7 members, strains, batches, docs, board, events) - TestResetController (profile-gated per-test DB reset) - docker-compose.test.yml (self-contained, tmpfs Postgres) - Dockerfile.playwright (v1.60.0, pre-installed deps) - 13 integration spec files, 70+ test cases (@smoke + @full) - seed-constants.ts, selectors.ts, api-client.ts test helpers
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package de.cannamanage.api.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test-only controller for resetting the database to a known seed state.
|
||||
* Only active when cannamanage.test.endpoints.enabled=true (test profile).
|
||||
* NEVER activate this in production.
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/test")
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "cannamanage.test.endpoints.enabled", havingValue = "true")
|
||||
public class TestResetController {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
/**
|
||||
* Truncates all application tables and re-seeds with test data.
|
||||
* The Flyway schema_history table is preserved.
|
||||
*/
|
||||
@PostMapping("/reset-db")
|
||||
public ResponseEntity<Void> resetDatabase() {
|
||||
log.info("Test DB reset requested — truncating all tables and re-seeding");
|
||||
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
truncateAllTables(conn);
|
||||
reseed();
|
||||
log.info("Test DB reset complete — seed data re-applied");
|
||||
return ResponseEntity.ok().build();
|
||||
} catch (SQLException e) {
|
||||
log.error("Failed to reset test database", e);
|
||||
return ResponseEntity.internalServerError().build();
|
||||
}
|
||||
}
|
||||
|
||||
private void truncateAllTables(Connection conn) throws SQLException {
|
||||
List<String> tables = getApplicationTables(conn);
|
||||
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
// Disable FK constraints for truncation
|
||||
stmt.execute("SET session_replication_role = 'replica'");
|
||||
|
||||
for (String table : tables) {
|
||||
stmt.execute("TRUNCATE TABLE " + table + " CASCADE");
|
||||
log.debug("Truncated table: {}", table);
|
||||
}
|
||||
|
||||
// Re-enable FK constraints
|
||||
stmt.execute("SET session_replication_role = 'origin'");
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getApplicationTables(Connection conn) throws SQLException {
|
||||
List<String> tables = new ArrayList<>();
|
||||
|
||||
try (Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT tablename FROM pg_tables " +
|
||||
"WHERE schemaname = 'public' " +
|
||||
"AND tablename != 'flyway_schema_history'")) {
|
||||
while (rs.next()) {
|
||||
tables.add(rs.getString("tablename"));
|
||||
}
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
private void reseed() {
|
||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||
populator.addScript(new ClassPathResource("db/testdata/R__seed_test_data.sql"));
|
||||
populator.setSeparator(";");
|
||||
populator.execute(dataSource);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# =============================================
|
||||
# application-test.properties
|
||||
# Profile: test — for integration test environment
|
||||
# Activate with: -Dspring.profiles.active=test
|
||||
# =============================================
|
||||
|
||||
# Database: use docker-compose.test.yml PostgreSQL
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5433/cannamanage_test
|
||||
spring.datasource.username=cannamanage_test
|
||||
spring.datasource.password=test_password
|
||||
spring.jpa.hibernate.ddl-auto=validate
|
||||
|
||||
# Flyway: include test seed data
|
||||
spring.flyway.enabled=true
|
||||
spring.flyway.locations=classpath:db/migration,classpath:db/testdata
|
||||
|
||||
# Enable test-only endpoints (TestResetController)
|
||||
cannamanage.test.endpoints.enabled=true
|
||||
|
||||
# Disable schedulers during test runs
|
||||
cannamanage.schedulers.enabled=false
|
||||
|
||||
# JWT: deterministic test secret (base64-encoded 256-bit key)
|
||||
cannamanage.security.jwt.secret=dGVzdC1zZWNyZXQta2V5LWZvci1pbnRlZ3JhdGlvbi10ZXN0cy1vbmx5LTMyYg==
|
||||
cannamanage.security.jwt.access-token-expiry=3600
|
||||
cannamanage.security.jwt.refresh-token-expiry=86400
|
||||
|
||||
# Logging
|
||||
logging.level.de.cannamanage=DEBUG
|
||||
logging.level.org.flywaydb=INFO
|
||||
logging.level.org.springframework.security=DEBUG
|
||||
@@ -0,0 +1,265 @@
|
||||
-- R__seed_test_data.sql — Repeatable Flyway migration for integration test data
|
||||
-- This file is idempotent: uses ON CONFLICT DO NOTHING for all inserts.
|
||||
-- Activated only when spring.flyway.locations includes classpath:db/testdata
|
||||
|
||||
-- ============================================================
|
||||
-- 1. CLUB
|
||||
-- ============================================================
|
||||
INSERT INTO clubs (id, tenant_id, name, address, license_number, max_members, status, created_at)
|
||||
VALUES (
|
||||
'a0000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001',
|
||||
'Grüner Daumen e.V.',
|
||||
'Hanfstraße 42, 10115 Berlin',
|
||||
'LIC-2024-GD-001',
|
||||
500,
|
||||
'ACTIVE',
|
||||
'2024-01-01T00:00:00Z'
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 2. MEMBERS (7)
|
||||
-- ============================================================
|
||||
INSERT INTO members (id, tenant_id, club_id, first_name, last_name, email, date_of_birth, membership_date, membership_number, status, is_under_21, prevention_officer, created_at)
|
||||
VALUES
|
||||
('c1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Max', 'Mustermann', 'max@gruener-daumen.de', '1990-05-20', '2024-01-15', 'GD-001', 'ACTIVE', FALSE, FALSE, '2024-01-15T10:00:00Z'),
|
||||
('c1000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Anna', 'Schmidt', 'anna@gruener-daumen.de', '1985-11-03', '2024-02-01', 'GD-002', 'ACTIVE', FALSE, FALSE, '2024-02-01T10:00:00Z'),
|
||||
('c1000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Jonas', 'Weber', 'jonas@gruener-daumen.de', '2006-03-15', '2024-03-10', 'GD-003', 'ACTIVE', TRUE, FALSE, '2024-03-10T10:00:00Z'),
|
||||
('c1000000-0000-0000-0000-000000000004', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Maria', 'Müller', 'maria@gruener-daumen.de', '1978-08-22', '2023-06-01', 'GD-004', 'SUSPENDED', FALSE, FALSE, '2023-06-01T10:00:00Z'),
|
||||
('c1000000-0000-0000-0000-000000000005', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Thomas', 'Müller', 'thomas@gruener-daumen.de', '1992-12-01', '2024-01-20', 'GD-005', 'ACTIVE', FALSE, FALSE, '2024-01-20T10:00:00Z'),
|
||||
('c1000000-0000-0000-0000-000000000006', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Lisa', 'Bauer', 'lisa@gruener-daumen.de', '1995-07-14', '2024-04-01', 'GD-006', 'ACTIVE', FALSE, FALSE, '2024-04-01T10:00:00Z'),
|
||||
('c1000000-0000-0000-0000-000000000007', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Karl', 'Fischer', 'karl@gruener-daumen.de', '1980-02-28', '2023-01-01', 'GD-007', 'EXPELLED', FALSE, FALSE, '2023-01-01T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 3. USERS (admin staff account)
|
||||
-- ============================================================
|
||||
INSERT INTO users (id, tenant_id, member_id, email, password_hash, role, active, created_at)
|
||||
VALUES (
|
||||
'b1000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001',
|
||||
'c1000000-0000-0000-0000-000000000001',
|
||||
'admin@gruener-daumen.de',
|
||||
'$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy',
|
||||
'ROLE_ADMIN',
|
||||
TRUE,
|
||||
'2024-01-15T10:00:00Z'
|
||||
) ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- Additional user accounts for members who need to author forum/info-board posts
|
||||
INSERT INTO users (id, tenant_id, member_id, email, password_hash, role, active, created_at)
|
||||
VALUES
|
||||
('b1000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000002',
|
||||
'anna.user@gruener-daumen.de', '$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy', 'ROLE_MEMBER', TRUE, '2024-02-01T10:00:00Z'),
|
||||
('b1000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000003',
|
||||
'jonas.user@gruener-daumen.de', '$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy', 'ROLE_MEMBER', TRUE, '2024-03-10T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 4. STRAINS (3)
|
||||
-- ============================================================
|
||||
INSERT INTO strains (id, tenant_id, name, thc_percentage, cbd_percentage, description, created_at)
|
||||
VALUES
|
||||
('d1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Northern Lights', 18.50, 0.50, 'Klassische Indica, entspannend und schmerzlindernd', '2024-04-01T10:00:00Z'),
|
||||
('d1000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001',
|
||||
'CBD Critical Mass', 5.00, 12.00, 'CBD-dominante Sorte für medizinische Anwendungen', '2024-04-01T10:00:00Z'),
|
||||
('d1000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Amnesia Haze', 22.00, 0.10, 'Starke Sativa mit hohem THC-Gehalt', '2024-04-01T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 5. BATCHES (3)
|
||||
-- ============================================================
|
||||
INSERT INTO batches (id, tenant_id, strain_id, quantity_grams, harvest_date, batch_code, status, contamination_flag, created_at)
|
||||
VALUES
|
||||
('e1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'd1000000-0000-0000-0000-000000000001', 500.00, '2024-04-25', 'NL-2024-001', 'AVAILABLE', FALSE, '2024-05-01T10:00:00Z'),
|
||||
('e1000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001',
|
||||
'd1000000-0000-0000-0000-000000000002', 300.00, '2024-05-10', 'CM-2024-001', 'AVAILABLE', FALSE, '2024-05-15T10:00:00Z'),
|
||||
('e1000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001',
|
||||
'd1000000-0000-0000-0000-000000000003', 200.00, '2024-03-20', 'AH-2024-001', 'RECALLED', TRUE, '2024-04-01T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 6. DISTRIBUTIONS (3 recent)
|
||||
-- ============================================================
|
||||
INSERT INTO distributions (id, tenant_id, member_id, batch_id, quantity_grams, distributed_at, recorded_by, notes, thc_percentage, cbd_percentage, strain_name, created_at)
|
||||
VALUES
|
||||
('dd000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'c1000000-0000-0000-0000-000000000001', 'e1000000-0000-0000-0000-000000000001',
|
||||
5.00, NOW() - INTERVAL '2 days', 'c1000000-0000-0000-0000-000000000001', 'Reguläre Abgabe',
|
||||
18.50, 0.50, 'Northern Lights', NOW() - INTERVAL '2 days'),
|
||||
('dd000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001',
|
||||
'c1000000-0000-0000-0000-000000000002', 'e1000000-0000-0000-0000-000000000002',
|
||||
3.00, NOW() - INTERVAL '1 day', 'c1000000-0000-0000-0000-000000000001', 'CBD-Abgabe',
|
||||
5.00, 12.00, 'CBD Critical Mass', NOW() - INTERVAL '1 day'),
|
||||
('dd000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001',
|
||||
'c1000000-0000-0000-0000-000000000005', 'e1000000-0000-0000-0000-000000000002',
|
||||
23.00, NOW(), 'c1000000-0000-0000-0000-000000000001', 'Nahe am Monatslimit (25g)',
|
||||
5.00, 12.00, 'CBD Critical Mass', NOW())
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 7. MONTHLY QUOTAS (Thomas near-quota)
|
||||
-- ============================================================
|
||||
INSERT INTO monthly_quotas (id, tenant_id, member_id, year, month, total_distributed, max_allowed, version, created_at)
|
||||
VALUES
|
||||
('mq000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'c1000000-0000-0000-0000-000000000005',
|
||||
EXTRACT(YEAR FROM NOW())::INT, EXTRACT(MONTH FROM NOW())::INT,
|
||||
23.00, 25.00, 1, NOW())
|
||||
ON CONFLICT (member_id, year, month) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 8. DOCUMENTS (4)
|
||||
-- ============================================================
|
||||
INSERT INTO documents (id, tenant_id, club_id, title, category, filename, content_type, file_size, storage_path, access_level, description, uploaded_by, created_at)
|
||||
VALUES
|
||||
('f1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Vereinssatzung 2024', 'SATZUNG', 'satzung-2024.pdf', 'application/pdf', 245000,
|
||||
'/documents/a0000000/satzung-2024.pdf', 'ALL_MEMBERS', 'Aktuelle Vereinssatzung gemäß §18 KCanG',
|
||||
'b1000000-0000-0000-0000-000000000001', '2024-01-15T10:00:00Z'),
|
||||
('f1000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Protokoll MV März 2024', 'PROTOKOLL', 'protokoll-mv-2024-03.pdf', 'application/pdf', 128000,
|
||||
'/documents/a0000000/protokoll-mv-2024-03.pdf', 'ALL_MEMBERS', 'Protokoll der Mitgliederversammlung vom 15.03.2024',
|
||||
'b1000000-0000-0000-0000-000000000001', '2024-03-16T10:00:00Z'),
|
||||
('f1000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'KCanG-Genehmigung', 'GENEHMIGUNG', 'kcang-genehmigung.pdf', 'application/pdf', 340000,
|
||||
'/documents/a0000000/kcang-genehmigung.pdf', 'BOARD_ONLY', 'Genehmigungsbescheid nach §11 KCanG',
|
||||
'b1000000-0000-0000-0000-000000000001', '2024-01-10T10:00:00Z'),
|
||||
('f1000000-0000-0000-0000-000000000004', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Mietvertrag', 'VERTRAG', 'mietvertrag-vereinsheim.pdf', 'application/pdf', 520000,
|
||||
'/documents/a0000000/mietvertrag-vereinsheim.pdf', 'BOARD_ONLY', 'Mietvertrag für Vereinsräume',
|
||||
'b1000000-0000-0000-0000-000000000001', '2023-12-01T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 9. BOARD POSITIONS (3)
|
||||
-- ============================================================
|
||||
INSERT INTO board_positions (id, tenant_id, club_id, title, description, sort_order, is_active, created_at)
|
||||
VALUES
|
||||
('g1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Vorsitzende/r', 'Erste/r Vorsitzende/r des Vereins', 1, TRUE, '2024-01-15T10:00:00Z'),
|
||||
('g1000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Kassenführung', 'Schatzmeister/in — Kassenführung und Finanzen', 2, TRUE, '2024-01-15T10:00:00Z'),
|
||||
('g1000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Schriftführung', 'Protokollführung und Korrespondenz', 3, TRUE, '2024-01-15T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- Board members (Max = Vorsitzender, Anna = Kassenführung, Schriftführung = vacant)
|
||||
INSERT INTO board_members (id, tenant_id, club_id, position_id, member_id, elected_at, term_start, is_current, created_at)
|
||||
VALUES
|
||||
('gm000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'g1000000-0000-0000-0000-000000000001', 'c1000000-0000-0000-0000-000000000001',
|
||||
'2024-01-15', '2024-01-15', TRUE, '2024-01-15T10:00:00Z'),
|
||||
('gm000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'g1000000-0000-0000-0000-000000000002', 'c1000000-0000-0000-0000-000000000002',
|
||||
'2024-01-15', '2024-01-15', TRUE, '2024-01-15T10:00:00Z')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 10. EVENTS (2)
|
||||
-- ============================================================
|
||||
INSERT INTO club_events (id, club_id, title, description, event_type, start_at, end_at, location, created_by, tenant_id, created_at, updated_at)
|
||||
VALUES
|
||||
('ev000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Mitgliederversammlung Q3', 'Ordentliche Mitgliederversammlung mit Vorstandswahl',
|
||||
'ASSEMBLY', NOW() + INTERVAL '14 days', NOW() + INTERVAL '14 days' + INTERVAL '2 hours',
|
||||
'Vereinsheim, Hanfstraße 42', 'b1000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001', NOW() - INTERVAL '7 days', NOW() - INTERVAL '7 days'),
|
||||
('ev000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Gartentag Mai', 'Gemeinsamer Gartentag — Pflege der Anbauflächen',
|
||||
'SOCIAL', NOW() - INTERVAL '30 days', NOW() - INTERVAL '30 days' + INTERVAL '4 hours',
|
||||
'Vereinsgarten', 'b1000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001', NOW() - INTERVAL '45 days', NOW() - INTERVAL '45 days')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 11. FORUM TOPICS (2) + REPLIES
|
||||
-- ============================================================
|
||||
INSERT INTO forum_topics (id, club_id, tenant_id, title, content, author_id, reply_count, last_reply_at, created_at)
|
||||
VALUES
|
||||
('ft000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Neue Sorten für Sommer', 'Welche Sorten sollen wir diesen Sommer anbauen? Ich schlage vor, mehr CBD-lastige Sorten zu probieren.',
|
||||
'b1000000-0000-0000-0000-000000000001', 3, NOW() - INTERVAL '2 days', NOW() - INTERVAL '10 days'),
|
||||
('ft000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Bewässerungssystem', 'Hat jemand Erfahrung mit automatischen Bewässerungssystemen für den Indoor-Bereich?',
|
||||
'b1000000-0000-0000-0000-000000000002', 1, NOW() - INTERVAL '5 days', NOW() - INTERVAL '7 days')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- Forum replies
|
||||
INSERT INTO forum_replies (id, topic_id, club_id, tenant_id, content, author_id, created_at)
|
||||
VALUES
|
||||
('fr000000-0000-0000-0000-000000000001', 'ft000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'CBD Critical Mass hat sich bei uns bewährt — guter Ertrag und medizinisch wertvoll!',
|
||||
'b1000000-0000-0000-0000-000000000002', NOW() - INTERVAL '9 days'),
|
||||
('fr000000-0000-0000-0000-000000000002', 'ft000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Finde ich gut! Vielleicht auch Charlotte''s Web als weitere CBD-Option?',
|
||||
'b1000000-0000-0000-0000-000000000003', NOW() - INTERVAL '7 days'),
|
||||
('fr000000-0000-0000-0000-000000000003', 'ft000000-0000-0000-0000-000000000001',
|
||||
'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Stimme zu — lasst uns in der MV darüber abstimmen.',
|
||||
'b1000000-0000-0000-0000-000000000001', NOW() - INTERVAL '2 days'),
|
||||
('fr000000-0000-0000-0000-000000000004', 'ft000000-0000-0000-0000-000000000002',
|
||||
'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Wir nutzen BlueMat-Tropfer — funktioniert super für Erde und Kokos.',
|
||||
'b1000000-0000-0000-0000-000000000001', NOW() - INTERVAL '5 days')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 12. INFO BOARD POSTS (2)
|
||||
-- ============================================================
|
||||
INSERT INTO info_board_posts (id, club_id, title, content, category, is_pinned, is_archived, author_id, tenant_id, created_at, updated_at)
|
||||
VALUES
|
||||
('ib000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Willkommen neue Mitglieder', 'Herzlich willkommen bei Grüner Daumen e.V.! Bitte lest die Vereinssatzung und meldet euch bei Fragen beim Vorstand.',
|
||||
'GENERAL', TRUE, FALSE, 'b1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
NOW() - INTERVAL '30 days', NOW() - INTERVAL '30 days'),
|
||||
('ib000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001',
|
||||
'Öffnungszeiten Sommer', 'Ab Juni gelten erweiterte Öffnungszeiten: Mo-Fr 10-20 Uhr, Sa 10-16 Uhr.',
|
||||
'MAINTENANCE', FALSE, FALSE, 'b1000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
NOW() - INTERVAL '14 days', NOW() - INTERVAL '14 days')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 13. GROW ENTRIES (2)
|
||||
-- ============================================================
|
||||
INSERT INTO grow_entries (id, name, strain_id, status, started_at, expected_harvest_at, notes, tenant_id, created_at, updated_at)
|
||||
VALUES
|
||||
('ge000000-0000-0000-0000-000000000001',
|
||||
'Northern Lights Batch #2', 'd1000000-0000-0000-0000-000000000001', 'VEGETATIVE',
|
||||
NOW() - INTERVAL '21 days', NOW() + INTERVAL '49 days',
|
||||
'Zweiter Indoor-Batch NL, 6 Pflanzen',
|
||||
'a0000000-0000-0000-0000-000000000001', NOW() - INTERVAL '21 days', NOW() - INTERVAL '1 day'),
|
||||
('ge000000-0000-0000-0000-000000000002',
|
||||
'CBD Outdoor', 'd1000000-0000-0000-0000-000000000002', 'SEEDLING',
|
||||
NOW() - INTERVAL '7 days', NOW() + INTERVAL '90 days',
|
||||
'Outdoor-Test mit CBD Critical Mass, 4 Pflanzen',
|
||||
'a0000000-0000-0000-0000-000000000001', NOW() - INTERVAL '7 days', NOW() - INTERVAL '1 day')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- 14. COMPLIANCE DEADLINES (3)
|
||||
-- ============================================================
|
||||
INSERT INTO compliance_deadlines (id, tenant_id, club_id, area, title, description, due_date, is_recurring, created_at)
|
||||
VALUES
|
||||
('cd000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'KCANG', 'Jahresbericht', 'Jährlicher Tätigkeitsbericht an die zuständige Behörde gemäß §22 KCanG',
|
||||
(CURRENT_DATE + INTERVAL '60 days')::DATE, TRUE, NOW() - INTERVAL '30 days'),
|
||||
('cd000000-0000-0000-0000-000000000002', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'FINANCE', 'EÜR Abgabe', 'Einnahmen-Überschuss-Rechnung an das Finanzamt',
|
||||
(CURRENT_DATE - INTERVAL '5 days')::DATE, FALSE, NOW() - INTERVAL '60 days'),
|
||||
('cd000000-0000-0000-0000-000000000003', 'a0000000-0000-0000-0000-000000000001', 'a0000000-0000-0000-0000-000000000001',
|
||||
'VEREIN', 'Mitgliederversammlung', 'Ordentliche Mitgliederversammlung (mindestens 1x jährlich)',
|
||||
(CURRENT_DATE + INTERVAL '14 days')::DATE, TRUE, NOW() - INTERVAL '14 days')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
Reference in New Issue
Block a user