Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34adb01cbb | ||
|
|
212a37f8dc | ||
|
|
5cd7fc305f | ||
|
|
9109e387b9 | ||
|
|
0d87574ea2 | ||
|
|
957e05342d | ||
|
|
e4f00c322d | ||
|
|
0cb063cdd7 | ||
|
|
282e2d3381 | ||
|
|
c471b7993f | ||
|
|
b1487c54d3 | ||
|
|
778a0a16e8 | ||
|
|
8fce19e3d4 | ||
|
|
74d87126ea | ||
|
|
4effafe3a1 | ||
|
|
cbe6326284 | ||
|
|
3a792c1a56 | ||
|
|
a14da5113f |
@@ -2,3 +2,9 @@
|
||||
|
||||
controllers:
|
||||
resource: routing.controllers
|
||||
|
||||
login_check:
|
||||
path: /login_check
|
||||
|
||||
api_logout:
|
||||
path: /api/logout
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
parameters:
|
||||
app.version: '0.1.11'
|
||||
app.version: '0.1.20'
|
||||
|
||||
@@ -185,27 +185,18 @@ sudo chmod 644 config/jwt/private.pem config/jwt/public.pem
|
||||
mkdir -p uploads
|
||||
```
|
||||
|
||||
### 8. Configurer Nginx systeme
|
||||
### 8. Configurer Nginx systeme (reverse proxy + maintenance)
|
||||
|
||||
Creer `/etc/nginx/sites-available/coltura.conf` :
|
||||
Copier la config reverse proxy depuis le repo :
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name coltura.malio-dev.fr;
|
||||
|
||||
client_max_body_size 55m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8083;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```bash
|
||||
sudo cp infra/prod/nginx-proxy.conf /etc/nginx/sites-available/coltura.conf
|
||||
```
|
||||
|
||||
Ou creer `/etc/nginx/sites-available/coltura.conf` manuellement (voir `infra/prod/nginx-proxy.conf`).
|
||||
|
||||
La config inclut le **mode maintenance** : si le fichier `/var/www/coltura/maintenance.on` existe, Nginx renvoie une 503 avec `maintenance.html`.
|
||||
|
||||
Activer le site :
|
||||
|
||||
```bash
|
||||
@@ -213,6 +204,18 @@ sudo ln -sf /etc/nginx/sites-available/coltura.conf /etc/nginx/sites-enabled/col
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### Mode maintenance
|
||||
|
||||
```bash
|
||||
# Activer la maintenance
|
||||
touch /var/www/coltura/maintenance.on
|
||||
|
||||
# Desactiver la maintenance
|
||||
rm /var/www/coltura/maintenance.on
|
||||
```
|
||||
|
||||
Optionnel : creer une page `/var/www/coltura/public/maintenance.html` personnalisee.
|
||||
|
||||
### 9. Deployer
|
||||
|
||||
```bash
|
||||
|
||||
48
frontend/components/ui/AppTopNav.vue
Normal file
48
frontend/components/ui/AppTopNav.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<header class="border-b border-neutral-200 bg-primary-500 px-3 py-2 text-white sm:px-5 sm:py-2 max-h-[60px]">
|
||||
<div class="flex h-full items-center justify-between">
|
||||
<MalioButtonIcon
|
||||
icon="mdi:menu"
|
||||
aria-label="Menu"
|
||||
variant="ghost"
|
||||
icon-size="24"
|
||||
button-class="lg:hidden text-white hover:bg-primary-600"
|
||||
@click="ui.openMobileSidebar()"
|
||||
/>
|
||||
<div class="hidden items-center gap-2 lg:flex">
|
||||
<h1 class="text-lg font-bold tracking-tight">Coltura</h1>
|
||||
</div>
|
||||
<div class="ml-auto flex items-center gap-4 text-xl text-white sm:gap-8">
|
||||
<div class="group relative flex gap-2 sm:gap-4">
|
||||
<Icon name="mdi:account-circle-outline" class="self-center cursor-pointer" size="36" />
|
||||
<p class="hidden self-center cursor-pointer sm:block">{{ user?.username }}</p>
|
||||
<div class="invisible absolute right-0 top-full z-50 mt-2 w-44 rounded-md border border-neutral-200 bg-white py-1 text-sm text-neutral-800 opacity-0 shadow-lg transition-all group-hover:visible group-hover:opacity-100">
|
||||
<button
|
||||
type="button"
|
||||
class="block w-full px-3 py-2 text-left hover:bg-neutral-100"
|
||||
@click="handleLogout"
|
||||
>
|
||||
Deconnexion
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { UserData } from '~/services/dto/user-data'
|
||||
|
||||
defineProps<{
|
||||
user?: UserData | null
|
||||
}>()
|
||||
|
||||
const auth = useAuthStore()
|
||||
const ui = useUiStore()
|
||||
|
||||
async function handleLogout() {
|
||||
await auth.logout()
|
||||
await navigateTo('/login')
|
||||
}
|
||||
</script>
|
||||
52
frontend/components/ui/SidebarLink.vue
Normal file
52
frontend/components/ui/SidebarLink.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<NuxtLink
|
||||
:to="to"
|
||||
class="group/link relative flex items-center transition-colors hover:text-primary-500"
|
||||
:class="linkClasses"
|
||||
:active-class="exact ? '' : activeClass"
|
||||
:exact-active-class="exact ? activeClass : ''"
|
||||
>
|
||||
<Icon :name="icon" :size="sub ? '20' : '24'" class="flex-shrink-0" />
|
||||
<span
|
||||
v-if="!collapsed"
|
||||
class="self-baseline whitespace-nowrap overflow-hidden transition-opacity duration-300"
|
||||
:class="sub ? 'text-sm' : 'text-md'"
|
||||
>
|
||||
{{ label }}
|
||||
</span>
|
||||
<div
|
||||
v-if="collapsed"
|
||||
class="pointer-events-none absolute left-full z-50 ml-2 rounded-md bg-neutral-800 px-2 py-1 text-xs text-white opacity-0 shadow-lg transition-opacity group-hover/link:pointer-events-auto group-hover/link:opacity-100 whitespace-nowrap"
|
||||
>
|
||||
{{ label }}
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
to: string
|
||||
icon: string
|
||||
label: string
|
||||
collapsed: boolean
|
||||
sub?: boolean
|
||||
exact?: boolean
|
||||
}>()
|
||||
|
||||
const activeClass = computed(() => {
|
||||
if (props.collapsed) {
|
||||
return '!text-primary-500 bg-primary-500/10'
|
||||
}
|
||||
return '!text-primary-500 bg-tertiary-500'
|
||||
})
|
||||
|
||||
const linkClasses = computed(() => {
|
||||
if (props.collapsed) {
|
||||
return 'justify-center w-10 h-10 mx-auto my-1 p-2 rounded-lg text-neutral-600 hover:text-primary-500 hover:bg-primary-500/10'
|
||||
}
|
||||
if (props.sub) {
|
||||
return 'gap-3 px-4 py-2 pl-12 text-sm font-semibold text-neutral-700'
|
||||
}
|
||||
return 'gap-3 px-4 py-3 text-md font-semibold text-neutral-700'
|
||||
})
|
||||
</script>
|
||||
@@ -126,10 +126,7 @@ export function useApi(): ApiClient {
|
||||
if (!isHandlingUnauthorized) {
|
||||
isHandlingUnauthorized = true
|
||||
auth.clearSession()
|
||||
const route = useRoute()
|
||||
if (route.path !== '/login') {
|
||||
await navigateTo('/login')
|
||||
}
|
||||
await navigateTo('/login')
|
||||
isHandlingUnauthorized = false
|
||||
}
|
||||
}
|
||||
|
||||
7
frontend/layouts/auth.vue
Normal file
7
frontend/layouts/auth.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="min-h-screen bg-tertiary-500 from-tertiary-500 via-white to-neutral-100 text-neutral-900">
|
||||
<main class="mx-auto flex min-h-screen w-full max-w-[720px] items-center px-6 py-12">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
43
frontend/package-lock.json
generated
43
frontend/package-lock.json
generated
@@ -570,29 +570,6 @@
|
||||
"integrity": "sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
|
||||
"integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
|
||||
"integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||
@@ -5730,16 +5707,6 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
@@ -12704,6 +12671,15 @@
|
||||
"url": "https://opencollective.com/svgo"
|
||||
}
|
||||
},
|
||||
"node_modules/svgo/node_modules/commander": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/tagged-tag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
|
||||
@@ -12809,6 +12785,7 @@
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
|
||||
"integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "coltura-frontend",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
"build:dist": "nuxt generate && rm -rf dist && cp -R .output/public dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@malio/layer-ui": "^1.2.0",
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/i18n": "^10.2.3",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
"nuxt": "^4.3.1",
|
||||
"nuxt-toast": "^1.4.0",
|
||||
"pinia": "^3.0.4",
|
||||
"vue": "^3.5.29",
|
||||
"vue-router": "^4.6.4"
|
||||
}
|
||||
"name": "coltura-frontend",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
"build:dist": "nuxt generate && rm -rf dist && cp -R .output/public dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@malio/layer-ui": "^1.2.2",
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/i18n": "^10.2.3",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
"nuxt": "^4.3.1",
|
||||
"nuxt-toast": "^1.4.0",
|
||||
"pinia": "^3.0.4",
|
||||
"vue": "^3.5.29",
|
||||
"vue-router": "^4.6.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,48 @@
|
||||
import type { Config } from 'tailwindcss'
|
||||
import type {Config} from 'tailwindcss'
|
||||
|
||||
export default <Partial<Config>>{
|
||||
content: [
|
||||
'./components/**/*.{vue,js,ts}',
|
||||
'./layouts/**/*.vue',
|
||||
'./pages/**/*.vue',
|
||||
'./composables/**/*.{js,ts}',
|
||||
'./plugins/**/*.{js,ts}',
|
||||
'./app.vue',
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['"Helvetica Neue"', 'Helvetica', 'Arial', 'sans-serif']
|
||||
},
|
||||
colors: {
|
||||
primary: {
|
||||
500: '#222783',
|
||||
},
|
||||
secondary: {
|
||||
500: '#304998'
|
||||
},
|
||||
tertiary: {
|
||||
500: '#F3F4F8'
|
||||
},
|
||||
blue: {
|
||||
500: '#056CF2'
|
||||
},
|
||||
m: {
|
||||
primary: 'rgb(var(--m-primary) / <alpha-value>)',
|
||||
secondary: 'rgb(var(--m-secondary, 75 77 237) / <alpha-value>)',
|
||||
tertiary: 'rgb(var(--m-tertiary, 243 244 248) / <alpha-value>)',
|
||||
border: 'rgb(var(--m-border) / <alpha-value>)',
|
||||
text: 'rgb(var(--m-text) / <alpha-value>)',
|
||||
muted: 'rgb(var(--m-muted) / <alpha-value>)',
|
||||
bg: 'rgb(var(--m-bg) / <alpha-value>)',
|
||||
surface: 'rgb(var(--m-surface) / <alpha-value>)',
|
||||
disabled: 'rgb(var(--m-disabled) / <alpha-value>)',
|
||||
danger: 'rgb(var(--m-danger) / <alpha-value>)',
|
||||
success: 'rgb(var(--m-success) / <alpha-value>)',
|
||||
'btn-primary': 'rgb(var(--m-btn-primary) / <alpha-value>)',
|
||||
'btn-primary-hover': 'rgb(var(--m-btn-primary-hover) / <alpha-value>)',
|
||||
'btn-primary-active': 'rgb(var(--m-btn-primary-active) / <alpha-value>)',
|
||||
'btn-secondary': 'rgb(var(--m-btn-secondary) / <alpha-value>)',
|
||||
'btn-secondary-hover': 'rgb(var(--m-btn-secondary-hover) / <alpha-value>)',
|
||||
'btn-secondary-active': 'rgb(var(--m-btn-secondary-active) / <alpha-value>)',
|
||||
'btn-danger': 'rgb(var(--m-btn-danger) / <alpha-value>)',
|
||||
'btn-danger-hover': 'rgb(var(--m-btn-danger-hover) / <alpha-value>)',
|
||||
'btn-danger-active': 'rgb(var(--m-btn-danger-active) / <alpha-value>)',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ POSTGRES_DB=coltura
|
||||
POSTGRES_USER=coltura
|
||||
POSTGRES_PASSWORD=CHANGE_ME_IN_PRODUCTION
|
||||
|
||||
APP_PORT=80
|
||||
|
||||
JWT_PASSPHRASE=CHANGE_ME_IN_PRODUCTION
|
||||
JWT_COOKIE_SECURE=1
|
||||
JWT_TOKEN_TTL=86400
|
||||
|
||||
@@ -58,6 +58,8 @@ RUN curl --insecure https://getcomposer.org/composer.phar -o /usr/bin/composer &
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
ENV APP_ENV=prod
|
||||
|
||||
# Copier les fichiers projet
|
||||
COPY . /var/www/html
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
container_name: php-coltura-fpm
|
||||
build:
|
||||
context: ../../
|
||||
dockerfile: infra/deploy/Dockerfile
|
||||
dockerfile: infra/prod/Dockerfile
|
||||
target: php-base
|
||||
environment:
|
||||
APP_ENV: prod
|
||||
@@ -19,12 +19,12 @@ services:
|
||||
container_name: nginx-coltura
|
||||
build:
|
||||
context: ../../
|
||||
dockerfile: infra/deploy/Dockerfile
|
||||
dockerfile: infra/prod/Dockerfile
|
||||
target: nginx
|
||||
depends_on:
|
||||
- php
|
||||
ports:
|
||||
- "${APP_PORT:-80}:80"
|
||||
- "8086:80"
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
|
||||
49
infra/prod/maintenance.html
Normal file
49
infra/prod/maintenance.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Maintenance en cours</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background-color: #f3f4f6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,0.10);
|
||||
padding: 48px 40px;
|
||||
max-width: 480px;
|
||||
text-align: center;
|
||||
}
|
||||
.icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
color: #111827;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
color: #6b7280;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🛠</div>
|
||||
<h1>Maintenance en cours</h1>
|
||||
<p>L'application est temporairement indisponible pour mise a jour. Elle sera de retour dans quelques instants.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
31
infra/prod/nginx-proxy.conf
Normal file
31
infra/prod/nginx-proxy.conf
Normal file
@@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name coltura.malio-dev.fr;
|
||||
|
||||
root /var/www/coltura/public;
|
||||
|
||||
# Maintenance mode
|
||||
if (-f /var/www/coltura/maintenance.on) {
|
||||
return 503;
|
||||
}
|
||||
|
||||
error_page 503 @maintenance;
|
||||
|
||||
location @maintenance {
|
||||
rewrite ^(.*)$ /maintenance.html break;
|
||||
}
|
||||
|
||||
location = /maintenance.html {
|
||||
internal;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8083;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 55m;
|
||||
}
|
||||
}
|
||||
32
migrations/Version20260407095546.php
Normal file
32
migrations/Version20260407095546.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260407095546 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE "user" (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, username VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649F85E0677 ON "user" (username)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP TABLE "user"');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user