feat: add list of aliases to note entity

One of the aliases can be primary for each note, but all can be used to get information from the apis.

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2021-06-06 17:46:32 +02:00
parent 7dd4f97d64
commit aaef0f72ba
6 changed files with 115 additions and 13 deletions

View file

@ -6,13 +6,20 @@ entity "note" {
*id : uuid <<generated>>
--
publicId: text
alias : text
*viewCount : number
*ownerId : uuid <<FK user>>
description: text
title: text
}
entity "alias" {
*id: uuid <<generated>>
---
name: text
' If the alias is primary. Can be NULL, which means it's not primary
primary: boolean
}
entity "user" {
*id : uuid <<generated>>
--
@ -169,6 +176,7 @@ media_upload "0..*" -- "1" note
note "1" -d- "1..*" revision
note "1" - "0..*" history_entry
note "0..*" -l- "0..*" tag
note "1" - "0..*" alias
note "0..*" -- "0..*" group
user "1..*" -- "0..*" group

63
src/notes/alias.entity.ts Normal file
View file

@ -0,0 +1,63 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import {
Column,
Entity,
ManyToOne,
PrimaryGeneratedColumn,
Unique,
} from 'typeorm';
import { Note } from './note.entity';
import { PrimaryValueTransformer } from './primary.value-transformer';
@Entity()
@Unique('Only one primary alias per note', ['note', 'primary'])
export class Alias {
@PrimaryGeneratedColumn('uuid')
id: string;
/**
* the actual alias
*/
@Column({
nullable: false,
unique: true,
})
name: string;
/**
* Is this alias the primary alias, by which people access the note?
*/
@Column({
/*
Because of the @Unique at the top of this entity, this field must be saved as null instead of false in the DB.
If a non-primary alias would be saved with `primary: false` it would only be possible to have one non-primary and one primary alias.
But a nullable field does not have such problems.
This way the DB keeps track that one note really only has one primary alias.
*/
comment:
'This field tells you if this is the primary alias of the note. If this field is null, that means this alias is not primary.',
nullable: true,
transformer: new PrimaryValueTransformer(),
})
primary: boolean;
@ManyToOne((_) => Note, (note) => note.aliases, {
onDelete: 'CASCADE', // This deletes the Alias, when the associated Note is deleted
})
note: Note;
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor() {}
static create(name: string, primary = false): Alias {
const alias = new Alias();
alias.name = name;
alias.primary = primary;
return alias;
}
}

View file

@ -25,13 +25,19 @@ export class NoteMetadataDto {
id: string;
/**
* Alias of the note
* Can be null
* All aliases of the note (including the primaryAlias)
*/
@IsArray()
@IsString({ each: true })
@ApiProperty()
aliases: string[];
/**
* The primary alias of the note
*/
@IsString()
@IsOptional()
@ApiPropertyOptional()
alias: string | null;
@ApiProperty()
primaryAlias: string | null;
/**
* Title of the note

View file

@ -19,6 +19,7 @@ import { NoteGroupPermission } from '../permissions/note-group-permission.entity
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
import { Revision } from '../revisions/revision.entity';
import { User } from '../users/user.entity';
import { Alias } from './alias.entity';
import { Tag } from './tag.entity';
import { generatePublicId } from './utils';
@ -28,12 +29,12 @@ export class Note {
id: string;
@Column({ type: 'text' })
publicId: string;
@Column({
unique: true,
nullable: true,
type: 'text',
})
alias: string | null;
@OneToMany(
(_) => Alias,
(alias) => alias.note,
{ cascade: true }, // This ensures that embedded Aliases are automatically saved to the database
)
aliases: Alias[];
@OneToMany(
(_) => NoteGroupPermission,
(groupPermission) => groupPermission.note,
@ -84,7 +85,7 @@ export class Note {
public static create(owner?: User, alias?: string): Note {
const newNote = new Note();
newNote.publicId = generatePublicId();
newNote.alias = alias ?? null;
newNote.aliases = alias ? [Alias.create(alias, true)] : [];
newNote.viewCount = 0;
newNote.owner = owner ?? null;
newNote.userPermissions = [];

View file

@ -14,6 +14,7 @@ import { NoteUserPermission } from '../permissions/note-user-permission.entity';
import { RevisionsModule } from '../revisions/revisions.module';
import { User } from '../users/user.entity';
import { UsersModule } from '../users/users.module';
import { Alias } from './alias.entity';
import { Note } from './note.entity';
import { NotesService } from './notes.service';
import { Tag } from './tag.entity';
@ -26,6 +27,7 @@ import { Tag } from './tag.entity';
NoteGroupPermission,
NoteUserPermission,
User,
Alias,
]),
forwardRef(() => RevisionsModule),
UsersModule,

View file

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ValueTransformer } from 'typeorm';
export class PrimaryValueTransformer implements ValueTransformer {
from(value: boolean | null): boolean {
if (value === null) {
return false;
}
return value;
}
to(value: boolean): boolean | null {
if (!value) {
return null;
}
return value;
}
}