feat(monorepo): migrate to typescript monorepo

This commit is contained in:
2025-11-07 17:09:29 +02:00
committed by BernardNganduDev
parent 3e09956f05
commit 075a388ccb
745 changed files with 2341 additions and 5082 deletions
+19
View File
@@ -0,0 +1,19 @@
<?php
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
Gesdinet\JWTRefreshTokenBundle\GesdinetJWTRefreshTokenBundle::class => ['all' => true],
Sentry\SentryBundle\SentryBundle::class => ['prod' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
];
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\Aggregator\Domain\Model\Entity\Article"
repository-class="Basango\Aggregator\Infrastructure\Persistence\Doctrine\ORM\ArticleOrmRepository"
table="article"
>
<id name="id" type="article_id">
<generator strategy="NONE" />
</id>
<field name="title" length="1024" />
<field name="body" type="text" />
<embedded name="link" class="Basango\Aggregator\Domain\Model\ValueObject\Link" use-column-prefix="false" />
<field name="hash" length="32" />
<field name="categories" type="text[]" nullable="true" />
<many-to-one field="source" target-entity="Basango\Aggregator\Domain\Model\Entity\Source" fetch="EAGER">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<embedded name="credibility" class="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Credibility" use-column-prefix="false" />
<field name="sentiment" enum-type="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Sentiment" length="30">
<options>
<option name="default">neutral</option>
</options>
</field>
<field name="metadata" type="open_graph" nullable="true" />
<embedded name="readingTime" class="Basango\Aggregator\Domain\Model\ValueObject\ReadingTime" use-column-prefix="false" />
<field name="tokenStatistics" type="token_statistics" nullable="true" />
<field name="image"
insertable="false"
updatable="false"
column-definition="VARCHAR(1024) GENERATED ALWAYS AS ((metadata->>'image')) STORED"
/>
<field
name="excerpt"
insertable="false"
updatable="false"
column-definition="VARCHAR(255) GENERATED ALWAYS AS ((left(body, 200) || '...')) STORED"
/>
<field name="publishedAt" type="datetime_immutable" />
<field name="crawledAt" type="datetime_immutable" />
<field name="updatedAt" type="datetime_immutable" nullable="true" />
</entity>
</doctrine-mapping>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\Aggregator\Domain\Model\Entity\Source"
repository-class="Basango\Aggregator\Infrastructure\Persistence\Doctrine\ORM\SourceOrmRepository"
table="source"
>
<id name="id" type="source_id">
<generator strategy="NONE"/>
</id>
<field name="url" />
<field name="name" />
<embedded name="credibility" class="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Credibility" use-column-prefix="false" />
<field name="displayName" nullable="true" />
<field name="description" length="1024" nullable="true" />
<field name="updatedAt" type="datetime_immutable" nullable="true"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\Aggregator\Domain\Model\ValueObject\Link">
<field name="link" length="1024" />
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\Aggregator\Domain\Model\ValueObject\ReadingTime">
<field name="readingTime" type="integer" nullable="true">
<options>
<option name="default">1</option>
<option name="unsigned">true</option>
</options>
</field>
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Credibility">
<field name="bias" enum-type="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Bias" length="30">
<options>
<option name="default">neutral</option>
</options>
</field>
<field name="reliability" enum-type="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Reliability" length="30">
<options>
<option name="default">reliable</option>
</options>
</field>
<field name="transparency" enum-type="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Transparency" length="30">
<options>
<option name="default">medium</option>
</options>
</field>
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\FeedManagement\Domain\Model\Entity\Bookmark"
repository-class="Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\ORM\BookmarkOrmRepository"
table="bookmark"
>
<id name="id" type="bookmark_id">
<generator strategy="NONE"/>
</id>
<many-to-one field="user" target-entity="Basango\IdentityAndAccess\Domain\Model\Entity\User" fetch="EAGER">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<field name="name" length="255" />
<field name="description" length="512" nullable="true" />
<field name="isPublic" type="boolean">
<options>
<option name="default">0</option>
</options>
</field>
<many-to-many field="articles" target-entity="Basango\Aggregator\Domain\Model\Entity\Article">
<join-table name="bookmark_article">
<join-columns>
<join-column name="bookmark_id" referenced-column-name="id" on-delete="CASCADE" />
</join-columns>
<inverse-join-columns>
<join-column name="article_id" referenced-column-name="id" on-delete="CASCADE" />
</inverse-join-columns>
</join-table>
</many-to-many>
<field name="createdAt" type="datetime_immutable"/>
<field name="updatedAt" type="datetime_immutable" nullable="true"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\FeedManagement\Domain\Model\Entity\Comment"
repository-class="Basango\FeedManagement\Infrastructure\Persistence\Doctrine\ORM\CommentOrmRepository"
table="comment"
>
<id name="id" type="comment_id">
<generator strategy="NONE"/>
</id>
<many-to-one field="user" target-entity="Basango\IdentityAndAccess\Domain\Model\Entity\User">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<many-to-one field="article" target-entity="Basango\Aggregator\Domain\Model\Entity\Article">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<field name="content" length="512" />
<field name="sentiment" enum-type="Basango\Aggregator\Domain\Model\ValueObject\Scoring\Sentiment" length="30">
<options>
<option name="default">neutral</option>
</options>
</field>
<field name="isSpam" type="boolean">
<options>
<option name="default">0</option>
</options>
</field>
<field name="createdAt" type="datetime_immutable"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\FeedManagement\Domain\Model\Entity\FollowedSource"
repository-class="Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\ORM\FollowedSourceOrmRepository"
table="followed_source"
>
<id name="id" type="followed_source_id">
<generator strategy="NONE"/>
</id>
<many-to-one field="follower" target-entity="Basango\IdentityAndAccess\Domain\Model\Entity\User">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<many-to-one field="source" target-entity="Basango\Aggregator\Domain\Model\Entity\Source">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<field name="createdAt" type="datetime_immutable"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\IdentityAndAccess\Domain\Model\Entity\LoginAttempt"
repository-class="Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\ORM\LoginAttemptOrmRepository"
table="login_attempt"
>
<id name="id" type="login_attempt_id">
<generator strategy="NONE"/>
</id>
<many-to-one field="user" target-entity="Basango\IdentityAndAccess\Domain\Model\Entity\User">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<field name="createdAt" type="datetime_immutable"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\IdentityAndAccess\Domain\Model\Entity\LoginHistory"
repository-class="Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\ORM\LoginAttemptOrmRepository"
table="login_history"
>
<id name="id" type="login_history_id">
<generator strategy="NONE"/>
</id>
<many-to-one field="user" target-entity="Basango\IdentityAndAccess\Domain\Model\Entity\User">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<field name="ipAddress" type="inet" nullable="true" length="15" />
<embedded name="device" class="Basango\SharedKernel\Domain\Model\ValueObject\Tracking\Device" />
<embedded name="location" class="Basango\SharedKernel\Domain\Model\ValueObject\Tracking\GeoLocation" />
<field name="createdAt" type="datetime_immutable"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\IdentityAndAccess\Domain\Model\Entity\RefreshToken"
repository-class="Gesdinet\JWTRefreshTokenBundle\Entity\RefreshTokenRepository"
table="refresh_tokens"
>
<id name="id" type="integer">
<generator strategy="SEQUENCE" />
<sequence-generator sequence-name="refresh_tokens_id_seq" allocation-size="100" initial-value="1" />
</id>
<field name="refreshToken" type="string" column="refresh_token" length="128" unique="true"/>
<field name="username" type="string" length="255" column="username"/>
<field name="valid" type="datetime"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\IdentityAndAccess\Domain\Model\Entity\User"
repository-class="Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\ORM\UserOrmRepository"
table="user"
>
<id name="id" type="user_id">
<generator strategy="NONE" />
</id>
<field name="name"/>
<field name="email" type="email" />
<field name="password" length="512" />
<embedded name="roles" class="Basango\IdentityAndAccess\Domain\Model\ValueObject\Roles" use-column-prefix="false" />
<field name="isLocked" type="boolean">
<options>
<option name="default">false</option>
</options>
</field>
<field name="isConfirmed" type="boolean">
<options>
<option name="default">false</option>
</options>
</field>
<field name="createdAt" type="datetime_immutable" />
<field name="updatedAt" type="datetime_immutable" nullable="true" />
</entity>
</doctrine-mapping>
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity
name="Basango\IdentityAndAccess\Domain\Model\Entity\VerificationToken"
repository-class="Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\ORM\VerificationTokenOrmRepository"
table="verification_token"
>
<id name="id" type="verification_token_id">
<generator strategy="NONE"/>
</id>
<many-to-one field="user" target-entity="Basango\IdentityAndAccess\Domain\Model\Entity\User" fetch="EAGER">
<join-column nullable="false" on-delete="CASCADE" />
</many-to-one>
<field name="purpose" enum-type="Basango\IdentityAndAccess\Domain\Model\ValueObject\Secret\TokenPurpose" />
<embedded name="token" class="Basango\IdentityAndAccess\Domain\Model\ValueObject\Secret\GeneratedToken" use-column-prefix="false" />
<field name="createdAt" type="datetime_immutable"/>
</entity>
</doctrine-mapping>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\IdentityAndAccess\Domain\Model\ValueObject\Roles">
<field name="roles" type="jsonb"/>
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\IdentityAndAccess\Domain\Model\ValueObject\Secret\GeneratedToken">
<field name="token" length="60" nullable="true" />
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\SharedKernel\Domain\Model\ValueObject\Tracking\Device">
<field name="operatingSystem" type="string" nullable="true" />
<field name="client" type="string" nullable="true" />
<field name="device" type="string" nullable="true" />
<field name="isBot" type="boolean" nullable="false" >
<options>
<option name="default">false</option>
</options>
</field>
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Basango\SharedKernel\Domain\Model\ValueObject\Tracking\GeoLocation">
<field name="timeZone" type="string" nullable="true"/>
<field name="longitude" type="float" nullable="true"/>
<field name="latitude" type="float" nullable="true" />
<field name="accuracyRadius" type="integer" nullable="true" />
</embeddable>
</doctrine-mapping>
@@ -0,0 +1,291 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\Migrations\Exception\IrreversibleMigration;
/**
* Class Version20251019151441.
*
* @author bernard-ng <bernard@devscast.tech>
*/
final class Version20251019151441 extends AbstractMigration
{
public function getDescription(): string
{
return 'initial postgresql schema';
}
public function up(Schema $schema): void
{
$this->addSql("CREATE EXTENSION IF NOT EXISTS pg_trgm;"); // for trigram indexes (links, titles, etc.)
$this->addSql("SET SESSION TIME ZONE 'UTC';");
// -- ---------- TABLE: article ----------
$this->addSql(<<<SQL
CREATE TABLE article (
id UUID NOT NULL,
source_id UUID NOT NULL,
title VARCHAR(1024) NOT NULL,
body TEXT NOT NULL,
hash VARCHAR(32) NOT NULL,
categories TEXT[] DEFAULT NULL,
sentiment VARCHAR(30) DEFAULT 'neutral' NOT NULL,
metadata JSONB DEFAULT NULL,
image VARCHAR(1024) GENERATED ALWAYS AS ((metadata->>'image')) STORED,
excerpt VARCHAR(255) GENERATED ALWAYS AS ((LEFT(body, 200) || '...')) STORED,
published_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
crawled_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL,
link VARCHAR(1024) NOT NULL,
bias VARCHAR(30) DEFAULT 'neutral' NOT NULL,
reliability VARCHAR(30) DEFAULT 'reliable' NOT NULL,
transparency VARCHAR(30) DEFAULT 'medium' NOT NULL,
reading_time INT DEFAULT 1,
CONSTRAINT CHK_ARTICLE_READING_TIME CHECK (reading_time >= 0),
CONSTRAINT CHK_ARTICLE_SENTIMENT CHECK (sentiment IN ('positive','neutral','negative')),
CONSTRAINT CHK_ARTICLE_METADATA_JSON CHECK (metadata IS NULL OR JSONB_TYPEOF(metadata) IN ('object','array')),
PRIMARY KEY (id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_23A0E66953C1C61 ON article (source_id)');
$this->addSql('CREATE INDEX IDX_ARTICLE_PUBLISHED_AT ON article (published_at DESC)');
$this->addSql('CREATE INDEX IDX_ARTICLE_PUBLISHED_ID ON article (published_at DESC, id DESC)');
$this->addSql('CREATE UNIQUE INDEX UNQ_ARTICLE_HASH ON article (hash)');
$this->addSql(<<<SQL
ALTER TABLE article ADD COLUMN tsv TSVECTOR GENERATED ALWAYS AS (
SETWEIGHT(TO_TSVECTOR('french', COALESCE(title,'')), 'A') ||
SETWEIGHT(TO_TSVECTOR('french', COALESCE(body ,'')), 'B')
) STORED;
SQL
);
$this->addSql('CREATE INDEX GIN_ARTICLE_TSV ON article USING GIN(tsv)');
$this->addSql('CREATE INDEX GIN_ARTICLE_LINK_TRGM ON article USING GIN (link gin_trgm_ops)');
$this->addSql('CREATE INDEX GIN_ARTICLE_TITLE_TRGM ON article USING GIN (title gin_trgm_ops)');
$this->addSql('CREATE INDEX GIN_ARTICLE_CATEGORIES ON article USING GIN (categories)');
$this->addSql("COMMENT ON COLUMN article.id IS '(DC2Type:article_id)';");
$this->addSql("COMMENT ON COLUMN article.source_id IS '(DC2Type:source_id)';");
$this->addSql("COMMENT ON COLUMN article.published_at IS '(DC2Type:datetime_immutable)'");
$this->addSql("COMMENT ON COLUMN article.crawled_at IS '(DC2Type:datetime_immutable)'");
$this->addSql("COMMENT ON COLUMN article.updated_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: bookmark ----------
$this->addSql(<<<SQL
CREATE TABLE bookmark (
id UUID NOT NULL,
user_id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
description VARCHAR(512) DEFAULT NULL,
is_public BOOLEAN DEFAULT false NOT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_DA62921DA76ED395 ON bookmark (user_id)');
$this->addSql('CREATE INDEX IDX_BOOKMARK_USER_CREATED ON bookmark (user_id, created_at DESC)');
$this->addSql("COMMENT ON COLUMN bookmark.id IS '(DC2Type:bookmark_id)'");
$this->addSql("COMMENT ON COLUMN bookmark.user_id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN bookmark.created_at IS '(DC2Type:datetime_immutable)'");
$this->addSql("COMMENT ON COLUMN bookmark.updated_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: bookmark_article ----------
$this->addSql(<<<SQL
CREATE TABLE bookmark_article (
bookmark_id UUID NOT NULL,
article_id UUID NOT NULL,
PRIMARY KEY(bookmark_id, article_id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_6FE2655D92741D25 ON bookmark_article (bookmark_id)');
$this->addSql('CREATE INDEX IDX_6FE2655D7294869C ON bookmark_article (article_id)');
$this->addSql("COMMENT ON COLUMN bookmark_article.bookmark_id IS '(DC2Type:bookmark_id)'");
$this->addSql("COMMENT ON COLUMN bookmark_article.article_id IS '(DC2Type:article_id)'");
// -- ---------- TABLE: comment ----------
$this->addSql(<<<SQL
CREATE TABLE comment (
id UUID NOT NULL,
user_id UUID NOT NULL,
article_id UUID NOT NULL,
content VARCHAR(512) NOT NULL,
sentiment VARCHAR(30) DEFAULT 'neutral' NOT NULL,
is_spam BOOLEAN DEFAULT false NOT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_9474526CA76ED395 ON comment (user_id)');
$this->addSql('CREATE INDEX IDX_9474526C7294869C ON comment (article_id)');
$this->addSql('CREATE INDEX IDX_COMMENT_ARTICLE_CREATED ON comment (article_id, created_at DESC)');
$this->addSql("COMMENT ON COLUMN comment.id IS '(DC2Type:comment_id)'");
$this->addSql("COMMENT ON COLUMN comment.user_id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN comment.article_id IS '(DC2Type:article_id)'");
$this->addSql("COMMENT ON COLUMN comment.created_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: followed_source ----------
$this->addSql(<<<SQL
CREATE TABLE followed_source (
id UUID NOT NULL,
follower_id UUID NOT NULL,
source_id UUID NOT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_7A763A3EAC24F853 ON followed_source (follower_id)');
$this->addSql('CREATE INDEX IDX_7A763A3E953C1C61 ON followed_source (source_id)');
$this->addSql('CREATE INDEX IDX_FOLLOWED_SOURCE_FOLLOWER_CREATED ON followed_source (follower_id, created_at DESC)');
$this->addSql("COMMENT ON COLUMN followed_source.id IS '(DC2Type:followed_source_id)'");
$this->addSql("COMMENT ON COLUMN followed_source.follower_id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN followed_source.source_id IS '(DC2Type:source_id)'");
$this->addSql("COMMENT ON COLUMN followed_source.created_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: login_attempt ----------
$this->addSql(<<<SQL
CREATE TABLE login_attempt (
id UUID NOT NULL,
user_id UUID NOT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_8C11C1BA76ED395 ON login_attempt (user_id)');
$this->addSql('CREATE INDEX IDX_LOGIN_ATTEMPT_CREATED_AT ON login_attempt (created_at DESC)');
$this->addSql("COMMENT ON COLUMN login_attempt.id IS '(DC2Type:login_attempt_id)'");
$this->addSql("COMMENT ON COLUMN login_attempt.user_id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN login_attempt.created_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: login_history ----------
$this->addSql(<<<SQL
CREATE TABLE login_history (
id UUID NOT NULL,
user_id UUID NOT NULL,
ip_address INET DEFAULT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
device_operating_system VARCHAR(255) DEFAULT NULL,
device_client VARCHAR(255) DEFAULT NULL,
device_device VARCHAR(255) DEFAULT NULL,
device_is_bot BOOLEAN DEFAULT false NOT NULL,
location_time_zone VARCHAR(255) DEFAULT NULL,
location_longitude DOUBLE PRECISION DEFAULT NULL,
location_latitude DOUBLE PRECISION DEFAULT NULL,
location_accuracy_radius INT DEFAULT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_37976E36A76ED395 ON login_history (user_id)');
$this->addSql('CREATE INDEX IDX_LOGIN_HISTORY_CREATED_AT ON login_history (user_id, created_at DESC)');
$this->addSql('CREATE INDEX IDX_LOGIN_HISTORY_IP_ADDRESS ON login_history (ip_address)');
$this->addSql("COMMENT ON COLUMN login_history.id IS '(DC2Type:login_history_id)'");
$this->addSql("COMMENT ON COLUMN login_history.user_id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN login_history.created_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: refresh_tokens ----------
$this->addSql('CREATE SEQUENCE refresh_tokens_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql(<<<SQL
CREATE TABLE refresh_tokens (
id INT NOT NULL,
refresh_token VARCHAR(128) NOT NULL,
username VARCHAR(255) NOT NULL,
valid TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE UNIQUE INDEX UNIQ_9BACE7E1C74F2195 ON refresh_tokens (refresh_token)');
// -- ---------- TABLE: source ----------
$this->addSql(<<<SQL
CREATE TABLE source (
id UUID NOT NULL,
url VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
display_name VARCHAR(255) DEFAULT NULL,
description VARCHAR(1024) DEFAULT NULL,
updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL,
bias VARCHAR(30) DEFAULT 'neutral' NOT NULL,
reliability VARCHAR(30) DEFAULT 'reliable' NOT NULL,
transparency VARCHAR(30) DEFAULT 'medium' NOT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE UNIQUE INDEX UNQ_SOURCE_NAME ON source (LOWER(name))');
$this->addSql('CREATE UNIQUE INDEX UNQ_SOURCE_URL ON source (LOWER(url))');
$this->addSql("COMMENT ON COLUMN source.id IS '(DC2Type:source_id)'");
$this->addSql("COMMENT ON COLUMN source.updated_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: user ----------
$this->addSql(<<<SQL
CREATE TABLE "user" (
id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
password VARCHAR(512) NOT NULL,
is_locked BOOLEAN DEFAULT false NOT NULL,
is_confirmed BOOLEAN DEFAULT false NOT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL,
roles JSONB NOT NULL,
PRIMARY KEY(id),
CONSTRAINT CHK_USER_ROLES_JSON CHECK (JSONB_TYPEOF(roles) = 'array')
)
SQL
);
$this->addSql(<<<SQL
CREATE UNIQUE INDEX UNQ_USER_EMAIL ON "user" (LOWER(email));
SQL
);
$this->addSql("COMMENT ON COLUMN \"user\".id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN \"user\".created_at IS '(DC2Type:datetime_immutable)'");
$this->addSql("COMMENT ON COLUMN \"user\".updated_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- TABLE: verification_token ----------
$this->addSql(<<<SQL
CREATE TABLE verification_token (
id UUID NOT NULL,
user_id UUID NOT NULL,
purpose VARCHAR(255) NOT NULL,
created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
token VARCHAR(60) DEFAULT NULL,
PRIMARY KEY(id)
)
SQL
);
$this->addSql('CREATE INDEX IDX_C1CC006BA76ED395 ON verification_token (user_id)');
$this->addSql('CREATE INDEX IDX_VERIF_TOKEN_CREATED_AT ON verification_token (created_at DESC)');
$this->addSql('CREATE UNIQUE INDEX UNQ_VERIF_USER_PURPOSE_TOKEN ON verification_token (user_id, purpose) WHERE token IS NOT NULL');
$this->addSql("COMMENT ON COLUMN verification_token.id IS '(DC2Type:verification_token_id)'");
$this->addSql("COMMENT ON COLUMN verification_token.user_id IS '(DC2Type:user_id)'");
$this->addSql("COMMENT ON COLUMN verification_token.created_at IS '(DC2Type:datetime_immutable)'");
// -- ---------- FOREIGN KEY CONSTRAINTS ----------
$this->addSql('ALTER TABLE article ADD CONSTRAINT FK_23A0E66953C1C61 FOREIGN KEY (source_id) REFERENCES source (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE bookmark ADD CONSTRAINT FK_DA62921DA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE bookmark_article ADD CONSTRAINT FK_6FE2655D92741D25 FOREIGN KEY (bookmark_id) REFERENCES bookmark (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE bookmark_article ADD CONSTRAINT FK_6FE2655D7294869C FOREIGN KEY (article_id) REFERENCES article (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE comment ADD CONSTRAINT FK_9474526CA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE comment ADD CONSTRAINT FK_9474526C7294869C FOREIGN KEY (article_id) REFERENCES article (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE followed_source ADD CONSTRAINT FK_7A763A3EAC24F853 FOREIGN KEY (follower_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE followed_source ADD CONSTRAINT FK_7A763A3E953C1C61 FOREIGN KEY (source_id) REFERENCES source (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE login_attempt ADD CONSTRAINT FK_8C11C1BA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE login_history ADD CONSTRAINT FK_37976E36A76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE verification_token ADD CONSTRAINT FK_C1CC006BA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema): void
{
throw new IrreversibleMigration('Sometimes in life you have to accept that you can\'t go back.');
}
}
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Class Version20251024234318.
*
* @author bernard-ng <bernard@devscast.tech>
*/
final class Version20251024234318 extends AbstractMigration
{
public function getDescription(): string
{
return 'add token statistics to article';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE article ADD token_statistics JSONB DEFAULT NULL');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE article DROP token_statistics');
}
}
@@ -0,0 +1,5 @@
framework:
cache:
pools:
cache.dbal:
adapter: cache.adapter.filesystem
@@ -0,0 +1,2 @@
maker:
root_namespace: Basango
@@ -0,0 +1,338 @@
doctrine:
dbal:
connections:
default:
url: '%env(resolve:DATABASE_URL)%'
server_version: '16'
profiling_collect_backtrace: false
idle_connection_ttl: 172800
use_savepoints: true
result_cache: 'cache.dbal'
mapping_types:
# Array type mappings
'bool[]': 'bool[]'
_bool: 'bool[]'
'smallint[]': 'smallint[]'
_int2: 'smallint[]'
'integer[]': 'integer[]'
_int4: 'integer[]'
'bigint[]': 'bigint[]'
_int8: 'bigint[]'
'double precision[]': 'double precision[]'
_float8: 'double precision[]'
'real[]': 'real[]'
_float4: 'real[]'
'text[]': 'text[]'
_text: 'text[]'
# JSON type mappings
jsonb: jsonb
'jsonb[]': 'jsonb[]'
_jsonb: 'jsonb[]'
# Network type mappings
cidr: cidr
'cidr[]': 'cidr[]'
_cidr: 'cidr[]'
inet: inet
'inet[]': 'inet[]'
_inet: 'inet[]'
macaddr: macaddr
'macaddr[]': 'macaddr[]'
_macaddr: 'macaddr[]'
# Spatial type mappings
point: point
'point[]': 'point[]'
_point: 'point[]'
geometry: geometry
'geometry[]': 'geometry[]'
_geometry: 'geometry[]'
geography: geography
'geography[]': 'geography[]'
_geography: 'geography[]'
# Range type mappings
daterange: daterange
int4range: int4range
int8range: int8range
numrange: numrange
tsrange: tsrange
tstzrange: tstzrange
# Hierarchical type mappings
ltree: ltree
types:
# Shared Kernel
email: Basango\SharedKernel\Infrastructure\Persistence\Doctrine\DBAL\Types\EmailType
# Aggregator
article_id: Basango\Aggregator\Infrastructure\Persistence\Doctrine\DBAL\Types\ArticleIdType
source_id: Basango\Aggregator\Infrastructure\Persistence\Doctrine\DBAL\Types\SourceIdType
open_graph: Basango\Aggregator\Infrastructure\Persistence\Doctrine\DBAL\Types\OpenGraphType
token_statistics: Basango\Aggregator\Infrastructure\Persistence\Doctrine\DBAL\Types\TokenStatisticsType
# Identity and Access
user_id: Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\DBAL\Types\UserIdType
login_attempt_id: Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\DBAL\Types\LoginAttemptIdType
login_history_id: Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\DBAL\Types\LoginHistoryIdType
verification_token_id: Basango\IdentityAndAccess\Infrastructure\Persistence\Doctrine\DBAL\Types\VerificationTokenIdType
# FeedManagement
bookmark_id: Basango\FeedManagement\Infrastructure\Persistence\Doctrine\DBAL\Types\BookmarkIdType
followed_source_id: Basango\FeedManagement\Infrastructure\Persistence\Doctrine\DBAL\Types\FollowedSourceIdType
comment_id: Basango\FeedManagement\Infrastructure\Persistence\Doctrine\DBAL\Types\CommentIdType
# PostgreSQL Specific Types
# Array types
'bool[]': MartinGeorgiev\Doctrine\DBAL\Types\BooleanArray
'smallint[]': MartinGeorgiev\Doctrine\DBAL\Types\SmallIntArray
'integer[]': MartinGeorgiev\Doctrine\DBAL\Types\IntegerArray
'bigint[]': MartinGeorgiev\Doctrine\DBAL\Types\BigIntArray
'double precision[]': MartinGeorgiev\Doctrine\DBAL\Types\DoublePrecisionArray
'real[]': MartinGeorgiev\Doctrine\DBAL\Types\RealArray
'text[]': MartinGeorgiev\Doctrine\DBAL\Types\TextArray
# JSON types
jsonb: MartinGeorgiev\Doctrine\DBAL\Types\Jsonb
'jsonb[]': MartinGeorgiev\Doctrine\DBAL\Types\JsonbArray
# Network types
cidr: MartinGeorgiev\Doctrine\DBAL\Types\Cidr
'cidr[]': MartinGeorgiev\Doctrine\DBAL\Types\CidrArray
inet: MartinGeorgiev\Doctrine\DBAL\Types\Inet
'inet[]': MartinGeorgiev\Doctrine\DBAL\Types\InetArray
macaddr: MartinGeorgiev\Doctrine\DBAL\Types\Macaddr
'macaddr[]': MartinGeorgiev\Doctrine\DBAL\Types\MacaddrArray
# Spatial types
point: MartinGeorgiev\Doctrine\DBAL\Types\Point
'point[]': MartinGeorgiev\Doctrine\DBAL\Types\PointArray
geometry: MartinGeorgiev\Doctrine\DBAL\Types\Geometry
'geometry[]': MartinGeorgiev\Doctrine\DBAL\Types\GeometryArray
geography: MartinGeorgiev\Doctrine\DBAL\Types\Geography
'geography[]': MartinGeorgiev\Doctrine\DBAL\Types\GeographyArray
# Range types
daterange: MartinGeorgiev\Doctrine\DBAL\Types\DateRange
int4range: MartinGeorgiev\Doctrine\DBAL\Types\Int4Range
int8range: MartinGeorgiev\Doctrine\DBAL\Types\Int8Range
numrange: MartinGeorgiev\Doctrine\DBAL\Types\NumRange
tsrange: MartinGeorgiev\Doctrine\DBAL\Types\TsRange
tstzrange: MartinGeorgiev\Doctrine\DBAL\Types\TstzRange
# Hierarchical types
ltree: MartinGeorgiev\Doctrine\DBAL\Types\Ltree
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
enable_native_lazy_objects: true
entity_managers:
default:
validate_xml_mapping: false
report_fields_where_declared: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
dql:
string_functions:
# alternative implementation of ALL() and ANY() where subquery is not required, useful for arrays
ALL_OF: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\All
ANY_OF: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Any
# operators for working with array and json(b) data
GREATEST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Greatest
LEAST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Least
CONTAINS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Contains # @>
IS_CONTAINED_BY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\IsContainedBy # <@
OVERLAPS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Overlaps # &&
RIGHT_EXISTS_ON_LEFT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\TheRightExistsOnTheLeft # ?
ALL_ON_RIGHT_EXIST_ON_LEFT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AllOnTheRightExistOnTheLeft # ?&
ANY_ON_RIGHT_EXISTS_ON_LEFT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AnyOnTheRightExistsOnTheLeft # ?|
RETURNS_VALUE_FOR_JSON_VALUE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ReturnsValueForJsonValue # @?
DELETE_AT_PATH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\DeleteAtPath # #-
# array and string specific functions
IN_ARRAY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\InArray
ANY_VALUE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\AnyValue
ARRAY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Arr
ARRAY_APPEND: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAppend
ARRAY_CARDINALITY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCardinality
ARRAY_CAT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayCat
ARRAY_DIMENSIONS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayDimensions
ARRAY_LENGTH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayLength
ARRAY_NUMBER_OF_DIMENSIONS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayNumberOfDimensions
ARRAY_POSITION: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayPosition
ARRAY_POSITIONS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayPositions
ARRAY_PREPEND: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayPrepend
ARRAY_REMOVE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayRemove
ARRAY_REPLACE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayReplace
ARRAY_SHUFFLE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayShuffle
ARRAY_TO_JSON: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayToJson
ARRAY_TO_STRING: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayToString
SPLIT_PART: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\SplitPart
STARTS_WITH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StartsWith
STRING_TO_ARRAY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StringToArray
UNNEST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Unnest
# json specific functions
JSON_ARRAY_LENGTH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonArrayLength
JSON_BUILD_OBJECT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonBuildObject
JSON_EACH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonEach
JSON_EACH_TEXT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonEachText
JSON_EXISTS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonExists
JSON_GET_FIELD: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetField
JSON_GET_FIELD_AS_INTEGER: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsInteger
JSON_GET_FIELD_AS_TEXT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsText
JSON_GET_OBJECT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetObject
JSON_GET_OBJECT_AS_TEXT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetObjectAsText
JSON_OBJECT_KEYS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonObjectKeys
JSON_QUERY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonQuery
JSON_SCALAR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonScalar
JSON_SERIALIZE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonSerialize
JSON_STRIP_NULLS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonStripNulls
JSON_TYPEOF: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonTypeof
JSON_VALUE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonValue
TO_JSON: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToJson
ROW_TO_JSON: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RowToJson
# jsonb specific functions
JSONB_ARRAY_ELEMENTS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElements
JSONB_ARRAY_ELEMENTS_TEXT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElementsText
JSONB_ARRAY_LENGTH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayLength
JSONB_BUILD_OBJECT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbBuildObject
JSONB_EACH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbEach
JSONB_EACH_TEXT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbEachText
JSONB_EXISTS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbExists
JSONB_INSERT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbInsert
JSONB_OBJECT_KEYS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectKeys
JSONB_PATH_EXISTS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathExists
JSONB_PATH_MATCH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathMatch
JSONB_PATH_QUERY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathQuery
JSONB_PATH_QUERY_ARRAY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathQueryArray
JSONB_PATH_QUERY_FIRST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathQueryFirst
JSONB_PRETTY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPretty
JSONB_SET: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbSet
JSONB_SET_LAX: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbSetLax
JSONB_STRIP_NULLS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbStripNulls
TO_JSONB: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToJsonb
# text search specific
TO_TSQUERY: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsquery
TO_TSVECTOR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTsvector
TSMATCH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsmatch
# date specific functions
DATE_ADD: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\DateAdd
DATE_BIN: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\DateBin
DATE_EXTRACT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\DateExtract
DATE_OVERLAPS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\DateOverlaps
DATE_SUBTRACT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\DateSubtract
# range functions
DATERANGE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Daterange
INT4RANGE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Int4range
INT8RANGE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Int8range
NUMRANGE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Numrange
TSRANGE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsrange
TSTZRANGE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tstzrange
# Arithmetic functions
CBRT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Cbrt
CEIL: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Ceil
DEGREES: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Degrees
EXP: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Exp
FLOOR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Floor
LN: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Ln
LOG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Log
PI: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Pi
POWER: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Power
RADIANS: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Radians
RANDOM: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Random
ROUND: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Round
SIGN: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Sign
TRUNC: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Trunc
WIDTH_BUCKET: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\WidthBucket
# other operators
CAST: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Cast
ILIKE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Ilike
SIMILAR_TO: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\SimilarTo
NOT_SIMILAR_TO: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NotSimilarTo
UNACCENT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Unaccent
REGEXP: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Regexp
IREGEXP: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\IRegexp
NOT_REGEXP: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NotRegexp
NOT_IREGEXP: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NotIRegexp
REGEXP_COUNT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpCount
REGEXP_INSTR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpInstr
REGEXP_LIKE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpLike
REGEXP_MATCH: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpMatch
REGEXP_REPLACE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpReplace
REGEXP_SUBSTR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpSubstr
ROW: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row
STRCONCAT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat
DISTANCE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance
# aggregation functions
ARRAY_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg
JSON_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonAgg
JSON_OBJECT_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonObjectAgg
JSONB_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbAgg
JSONB_OBJECT_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectAgg
STRING_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StringAgg
XML_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\XmlAgg
# data type formatting functions
TO_CHAR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToChar
TO_DATE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToDate
TO_NUMBER: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToNumber
TO_TIMESTAMP: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ToTimestamp
mappings:
Aggregator:
is_bundle: false
type: xml
dir: '%kernel.project_dir%/config/doctrine/Aggregator'
prefix: 'Basango\Aggregator\Domain\Model'
IdentityAndAccess:
is_bundle: false
type: xml
dir: '%kernel.project_dir%/config/doctrine/IdentityAndAccess'
prefix: 'Basango\IdentityAndAccess\Domain\Model'
FeedManagement:
is_bundle: false
type: xml
dir: '%kernel.project_dir%/config/doctrine/FeedManagement'
prefix: 'Basango\FeedManagement\Domain\Model'
SharedKernel:
is_bundle: false
type: xml
dir: '%kernel.project_dir%/config/doctrine/SharedKernel'
prefix: 'Basango\SharedKernel\Domain\Model'
controller_resolver:
auto_mapping: false
when@test:
doctrine:
dbal:
# "TEST_TOKEN" is typically set by ParaTest
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
when@prod:
doctrine:
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system
@@ -0,0 +1,6 @@
doctrine_migrations:
migrations_paths:
# namespace is arbitrary but should be different from Basango\Migrations
# as migrations classes should NOT be autoloaded
'DoctrineMigrations': '%kernel.project_dir%/config/migrations'
enable_profiler: false
@@ -0,0 +1,25 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
http_method_override: false
handle_all_throwables: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
#esi: true
#fragments: true
php_errors:
log: true
when@test:
framework:
test: true
session:
storage_factory_id: session.storage.factory.mock_file
@@ -0,0 +1,4 @@
gesdinet_jwt_refresh_token:
refresh_token_class: Basango\IdentityAndAccess\Domain\Model\Entity\RefreshToken
ttl: 2592000 # 1 month
ttl_update: true
@@ -0,0 +1,5 @@
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: '%env(resolve:JWT_TTL)%'
@@ -0,0 +1,3 @@
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
@@ -0,0 +1,39 @@
framework:
messenger:
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
failure_transport: failed
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
retry_strategy:
max_retries: 3
delay: 1000
multiplier: 2
max_delay: 0
options:
auto_setup: true
failed:
dsn: 'doctrine://default?queue_name=failed'
options:
auto_setup: true
sync: 'sync://'
routing:
Basango\SharedKernel\Application\Messaging\AsyncMessage: async
Symfony\Component\Mailer\Messenger\SendEmailMessage: sync
default_bus: command.bus
buses:
command.bus: ~
query.bus: ~
message.bus: ~
when@test:
framework:
messenger:
transports:
# replace with your transport name here (e.g., my_transport: 'in-memory://')
# For more Messenger testing tools, see https://github.com/zenstruck/messenger-test
async: 'in-memory://'
@@ -0,0 +1,72 @@
monolog:
channels:
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
when@dev:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!app"]
app:
type: stream
path: "%kernel.logs_dir%/app.%kernel.environment%.log"
level: debug
channels: ["app"]
console:
type: console
level: debug
process_psr_3_messages: false
channels: ["app"]
when@test:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!event"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
when@prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
telegram:
type: telegram
level: critical
channels: [ "!event" ]
token: "%env(DEVY_TOKEN)%"
channel: "%env(DEVY_CHANNEL)%"
topic: "%env(int:DEVY_TOPIC)%"
parse_mode: "MarkdownV2"
disable_webpage_preview: true
disable_notification: false
split_long_messages: false
formatter: Basango\SharedKernel\Infrastructure\Framework\Symfony\Logging\TelegramFormatter
nested:
type: rotating_file
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: error
max_files: 10
console:
type: console
level: info
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: [deprecation]
path: "%kernel.logs_dir%/deprecation.log"
@@ -0,0 +1,12 @@
framework:
router:
utf8: true
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
#default_uri: http://localhost
when@prod:
framework:
router:
strict_requirements: null
@@ -0,0 +1,62 @@
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
app_user_provider:
id: Basango\IdentityAndAccess\Infrastructure\Framework\Symfony\Security\SecurityUserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security:
login:
pattern: ^/api/login
stateless: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
user_checker: Basango\IdentityAndAccess\Infrastructure\Framework\Symfony\Security\UserChecker
api:
pattern: ^/api
stateless: true
entry_point: jwt
jwt: ~
refresh_jwt:
check_path: /api/token/refresh
logout:
path: api_token_invalidate
user_checker: Basango\IdentityAndAccess\Infrastructure\Framework\Symfony\Security\UserChecker
main:
lazy: true
provider: app_user_provider
user_checker: Basango\IdentityAndAccess\Infrastructure\Framework\Symfony\Security\UserChecker
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/api/register, roles: PUBLIC_ACCESS }
- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api/token/refresh, roles: PUBLIC_ACCESS }
- { path: ^/api/password/(request|reset), roles: PUBLIC_ACCESS }
- { path: ^/api/account/(unlock|confirm), roles: PUBLIC_ACCESS }
- { path: ^/api/aggregator/articles, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon
@@ -0,0 +1,24 @@
when@prod:
sentry:
dsn: "%env(SENTRY_DSN)%"
register_error_listener: false
register_error_handler: false
options:
traces_sample_rate: 0.1
ignore_exceptions:
- 'Symfony\Component\ErrorHandler\Error\FatalError'
- 'Symfony\Component\Debug\Exception\FatalErrorException'
monolog:
handlers:
sentry_fingers_crossed:
type: fingers_crossed
action_level: error
handler: sentry
excluded_http_codes: [404, 405]
buffer_size: 50
sentry:
type: sentry
level: !php/const Monolog\Logger::ERROR
hub_id: Sentry\State\HubInterface
fill_extra_context: true
process_psr_3_messages: false
@@ -0,0 +1,7 @@
framework:
default_locale: fr
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
providers:
+16
View File
@@ -0,0 +1,16 @@
twig:
file_name_pattern: '*.twig'
date:
format: 'd M Y'
interval_format: '%d days'
timezone: null
number_format:
decimals: 2
decimal_point: ','
thousands_separator: '.'
globals:
'application': '@Basango\SharedKernel\Domain\Application'
when@test:
twig:
strict_variables: true
@@ -0,0 +1,11 @@
framework:
validation:
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
#auto_mapping:
# App\Entity\: []
when@test:
framework:
validation:
not_compromised_password: false
@@ -0,0 +1,11 @@
when@dev:
web_profiler:
toolbar: true
framework:
profiler:
collect_serializer_data: true
when@test:
framework:
profiler: { collect: false }
+5
View File
@@ -0,0 +1,5 @@
<?php
if (file_exists(dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php';
}
+27
View File
@@ -0,0 +1,27 @@
controllers:
resource: ../src/
type: attribute
schemes:
- HTTP
- HTTPS
identity_and_access_login_check:
path: /api/login_check
methods: [POST]
schemes:
- HTTP
- HTTPS
identity_and_access_refresh_token:
path: /api/token/refresh
methods: [POST]
schemes:
- HTTP
- HTTPS
identity_and_access_token_invalidate:
path: /api/token/invalidate
methods: [POST]
schemes:
- HTTP
- HTTPS
@@ -0,0 +1,4 @@
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error
@@ -0,0 +1,2 @@
gesdinet_jwt_refresh_token:
path: /api/token/refresh
@@ -0,0 +1,3 @@
_security_logout:
resource: security.route_loader.logout
type: service
@@ -0,0 +1,8 @@
when@dev:
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
prefix: /_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
prefix: /_profiler
+55
View File
@@ -0,0 +1,55 @@
# This file is the entry point to configure your own process.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
basango_notification_email: '%env(BASANGO_NOTIFICATION_EMAIL)%'
services:
# default configuration for process in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your process.
autoconfigure: true # Automatically registers your process as commands, event subscribers, etc.
bind:
$projectDir: '%kernel.project_dir%'
$crawlingNotificationEmail: '%basango_notification_email%'
_instanceof:
Basango\SharedKernel\Application\Messaging\CommandHandler:
tags:
- { name: messenger.message_handler, bus: 'command.bus' }
Basango\SharedKernel\Application\Messaging\QueryHandler:
tags:
- { name: messenger.message_handler, bus: 'query.bus' }
Basango\SharedKernel\Application\Messaging\MessageHandler:
tags:
- { name: messenger.message_handler, bus: 'message.bus' }
Basango\SharedKernel\Domain\EventListener\EventListener:
tags:
- { name: kernel.event_listener }
Symfony\Bridge\Monolog\Processor\ConsoleCommandProcessor:
tags:
- { name: monolog.processor, channel: 'app' }
Symfony\Bridge\Monolog\Processor\RouteProcessor:
tags:
- { name: monolog.processor, channel: 'app' }
Symfony\Bridge\Monolog\Processor\TokenProcessor:
tags:
- { name: monolog.processor, channel: 'app' }
Basango\SharedKernel\Infrastructure\Framework\Symfony\Logging\TelegramFormatter:
tags:
- { name: monolog.formatter }
# makes classes in src/ available to be used as process
# this creates a service per class whose id is the fully-qualified class name
Basango\:
resource: '../src/'
exclude:
- '../src/SharedKernel/Infrastructure/Framework/Symfony/Kernel.php'
- '../src/**/Domain/Model/Entity/*'
- '../src/**/Domain/Model/ValueObject/*'
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
@@ -0,0 +1,7 @@
services:
_defaults:
autowire: true
autoconfigure: true
Tests\Behat\:
resource: '../tests/Behat/*'