Added all EmployeeController requests, except registration.

Fixed Entities and database relations
Fixed door opening
This commit is contained in:
Индекс Зиро 2025-02-19 11:34:45 +03:00
parent 413d071443
commit 3edb2cf101
22 changed files with 220 additions and 93 deletions

View File

@ -4,7 +4,6 @@ import com.indexzero.finals.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer; import org.springframework.security.config.Customizer;
@ -31,6 +30,11 @@ public class SecurityConfig {
.requestMatchers("/v3/api-docs/**").permitAll() .requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/api/employee/login").authenticated() .requestMatchers("/api/employee/login").authenticated()
.requestMatchers("/api/employee/profile").authenticated() .requestMatchers("/api/employee/profile").authenticated()
.requestMatchers("/api/employee/{login}/delete").hasAuthority("ADMIN")
.requestMatchers("/api/employee/{login}/{state}").hasAuthority("ADMIN")
.requestMatchers("/api/employee/all").hasAuthority("ADMIN")
.requestMatchers("/api/employee/{login}").hasAuthority("ADMIN")
.requestMatchers("/swagger-ui/**").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.httpBasic(Customizer.withDefaults()).csrf(csrf -> csrf .httpBasic(Customizer.withDefaults()).csrf(csrf -> csrf

View File

@ -0,0 +1,22 @@
package com.indexzero.finals.controller;
import com.indexzero.finals.entity.Entrance;
import com.indexzero.finals.repository.EntranceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/entrance")
public class CodeController {
@Autowired
EntranceRepository visitRepository;
@GetMapping
public List<Entrance> getVisits() {
return visitRepository.findAll();
}
}

View File

@ -1,15 +1,10 @@
package com.indexzero.finals.controller; package com.indexzero.finals.controller;
import com.indexzero.finals.dto.EmployeeDTO; import com.indexzero.finals.dto.EmployeeDTO;
import com.indexzero.finals.entity.Code;
import com.indexzero.finals.entity.Employee;
import com.indexzero.finals.entity.Visit;
import com.indexzero.finals.repository.CodeRepository;
import com.indexzero.finals.repository.EmployeeRepository;
import com.indexzero.finals.repository.VisitRepository;
import com.indexzero.finals.service.EmployeeService; import com.indexzero.finals.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -39,4 +34,24 @@ public class EmployeeController {
return employeeService.openTheDoor(code, SecurityContextHolder.getContext().getAuthentication()); return employeeService.openTheDoor(code, SecurityContextHolder.getContext().getAuthentication());
} }
@DeleteMapping("/{login}/delete")
public ResponseEntity<HttpStatusCode> delete(@PathVariable String login) {
return employeeService.deleteEmployee(login);
}
@PatchMapping("/{login}/{state}")
public ResponseEntity<HttpStatusCode> changeState(@PathVariable String login, @PathVariable String state) {
return employeeService.changeState(login, state);
}
@GetMapping("/all")
public ResponseEntity<List<EmployeeDTO>> getAll() {
return employeeService.getAllEmployees();
}
@GetMapping("/{login}")
public ResponseEntity<EmployeeDTO> getEmployeeByLogin(@PathVariable String login) {
return employeeService.getEmployeeByLogin(login);
}
} }

View File

@ -20,6 +20,6 @@ public class Code {
@Column(name = "value") @Column(name = "value")
private long value; private long value;
@Column(name = "is_active") @Column(name = "name")
boolean isActive; String name;
} }

View File

@ -7,8 +7,6 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -38,14 +36,22 @@ public class Employee implements UserDetails {
@Column(name = "photo_url") @Column(name = "photo_url")
private String photoUrl; private String photoUrl;
@Column(name = "is_enabled")
Boolean isEmpEnabled;
@ManyToMany(fetch = FetchType.EAGER) @ManyToMany(fetch = FetchType.EAGER)
Set<Authority> authorities; Set<Authority> authorities;
@OneToMany(mappedBy = "id") @OneToMany(mappedBy = "id", cascade = CascadeType.ALL)
List<Visit> visits; List<Entrance> entrances;
@Override @Override
public String getUsername() { public String getUsername() {
return this.login; return this.login;
} }
@Override
public boolean isEnabled() {
return isEmpEnabled;
}
} }

View File

@ -0,0 +1,34 @@
package com.indexzero.finals.entity;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "employee_entrances")
public class Entrance {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "visit_time")
private LocalDateTime visitTime;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employee_id", referencedColumnName = "id")
private Employee employee;
// @OneToOne
// @JoinColumn(name = "employee_id", referencedColumnName = "id")
// private Employee employee;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "reader", referencedColumnName = "id")
private Code reader;
@Column(name = "type")
private String type;
}

View File

@ -1,25 +0,0 @@
package com.indexzero.finals.entity;
import jakarta.persistence.*;
import lombok.Data;
import org.apache.catalina.User;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
@Data
@Entity
@Table(name = "employee_visits")
public class Visit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "visit_time")
private LocalDateTime visitTime;
@Column(name = "type")
private String type;
}

View File

@ -0,0 +1,7 @@
package com.indexzero.finals.repository;
import com.indexzero.finals.entity.Entrance;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EntranceRepository extends JpaRepository<Entrance, Long> {
}

View File

@ -1,7 +0,0 @@
package com.indexzero.finals.repository;
import com.indexzero.finals.entity.Visit;
import org.springframework.data.jpa.repository.JpaRepository;
public interface VisitRepository extends JpaRepository<Visit, Long> {
}

View File

@ -1,13 +1,19 @@
package com.indexzero.finals.service; package com.indexzero.finals.service;
import com.indexzero.finals.dto.EmployeeDTO; import com.indexzero.finals.dto.EmployeeDTO;
import com.indexzero.finals.entity.Employee;
import org.apache.catalina.User; import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import java.util.List;
public interface EmployeeService { public interface EmployeeService {
ResponseEntity<Object> checkIfUserExists(String login); ResponseEntity<Object> checkIfUserExists(String login);
ResponseEntity<EmployeeDTO> getUserInfo(Authentication auth); ResponseEntity<EmployeeDTO> getUserInfo(Authentication auth);
ResponseEntity<Object> openTheDoor(Long code, Authentication auth); ResponseEntity<Object> openTheDoor(Long code, Authentication auth);
ResponseEntity<HttpStatusCode> deleteEmployee(String login);
ResponseEntity<HttpStatusCode> changeState(String login, String state);
ResponseEntity<List<EmployeeDTO>> getAllEmployees();
ResponseEntity<EmployeeDTO> getEmployeeByLogin(String login);
} }

View File

@ -2,20 +2,23 @@ package com.indexzero.finals.service.impl;
import com.indexzero.finals.dto.EmployeeDTO; import com.indexzero.finals.dto.EmployeeDTO;
import com.indexzero.finals.entity.Employee; import com.indexzero.finals.entity.Employee;
import com.indexzero.finals.entity.Visit; import com.indexzero.finals.entity.Entrance;
import com.indexzero.finals.repository.CodeRepository; import com.indexzero.finals.repository.CodeRepository;
import com.indexzero.finals.repository.EmployeeRepository; import com.indexzero.finals.repository.EmployeeRepository;
import com.indexzero.finals.repository.EntranceRepository;
import com.indexzero.finals.service.EmployeeService; import com.indexzero.finals.service.EmployeeService;
import com.indexzero.finals.util.EmployeeMapper; import com.indexzero.finals.util.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service @Service
public class EmployeeServiceImpl implements EmployeeService { public class EmployeeServiceImpl implements EmployeeService {
@ -24,6 +27,8 @@ public class EmployeeServiceImpl implements EmployeeService {
@Autowired @Autowired
CodeRepository codeRepository; CodeRepository codeRepository;
@Autowired
private EntranceRepository entranceRepository;
public ResponseEntity<Object> checkIfUserExists(String login) { public ResponseEntity<Object> checkIfUserExists(String login) {
try { try {
@ -46,34 +51,89 @@ public class EmployeeServiceImpl implements EmployeeService {
public ResponseEntity<Object> openTheDoor(Long code, Authentication auth) { public ResponseEntity<Object> openTheDoor(Long code, Authentication auth) {
try { try {
if(codeRepository.findByValue(code).isActive()) { if (codeRepository.existsByValue(Long.valueOf(code))) {
if (codeRepository.existsByValue(Long.valueOf(code))) { Employee employee = employeeRepository.findByLogin(auth.getName());
Employee employee = employeeRepository.findByLogin(auth.getName()); Entrance entrance = new Entrance();
Visit visit = new Visit(); entrance.setVisitTime(LocalDateTime.now());
entrance.setReader(codeRepository.findByValue(code));
entrance.setType("smartphone");
entrance.setEmployee(employee);
LocalDateTime time = LocalDateTime.now(); entranceRepository.save(entrance);
visit.setVisitTime(LocalDateTime.now());
visit.setType("smartphone");
List<Visit> v = employee.getVisits(); // employeeRepository.save(employee);
v.add(visit);
employee.setVisits(v); return new ResponseEntity<>(HttpStatus.OK);
employeeRepository.save(employee);
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
} }
else { else {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
} }
} }
catch(Exception e) { catch(Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} }
} }
@Override
public ResponseEntity<HttpStatusCode> deleteEmployee(String login) {
Employee e = employeeRepository.findByLogin(login);
if(e != null) {
if (Objects.equals(e.getAuthorities().iterator().next().getAuthority(), "ADMIN")) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
else {
employeeRepository.delete(e);
return new ResponseEntity<>(HttpStatus.OK);
}
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@Override
public ResponseEntity<HttpStatusCode> changeState(String login, String state) {
Employee e = employeeRepository.findByLogin(login);
if(e != null) {
if (Objects.equals(e.getAuthorities().iterator().next().getAuthority(), "ADMIN")) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
else {
if(state.equals("active")) {
e.setIsEmpEnabled(true);
employeeRepository.save(e);
return new ResponseEntity<>(HttpStatus.OK);
}
else if(state.equals("blocked")) {
e.setIsEmpEnabled(false);
employeeRepository.save(e);
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@Override
public ResponseEntity<List<EmployeeDTO>> getAllEmployees() {
return new ResponseEntity<>(employeeRepository.findAll().stream().map(EmployeeMapper::convertToDTO).collect(Collectors.toList()), HttpStatus.OK);
}
@Override
public ResponseEntity<EmployeeDTO> getEmployeeByLogin(String login) {
Employee e = employeeRepository.findByLogin(login);
if(e != null) {
return new ResponseEntity<>(EmployeeMapper.convertToDTO(e), HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
} }

View File

@ -23,7 +23,8 @@
<column name="value" type="bigint"> <column name="value" type="bigint">
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>
<column name="is_active" type="bool">
<column name="name" type="VARCHAR(200)">
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>
</createTable> </createTable>

View File

@ -38,6 +38,10 @@
</column> </column>
<column name="photo_url" type="VARCHAR(100)"> <column name="photo_url" type="VARCHAR(100)">
<constraints nullable="true"/>
</column>
<column name="is_enabled" type="bool">
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>

View File

@ -5,19 +5,19 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="2025-02-18--0005-visits" author="okalugin"> <changeSet id="2025-02-19--0005-employee-entrances-02" author="okalugin">
<preConditions> <preConditions>
<not> <not>
<tableExists tableName="employee_visits"/> <tableExists tableName="employee_entrances"/>
</not> </not>
</preConditions> </preConditions>
<createTable tableName="employee_visits"> <createTable tableName="employee_entrances">
<column name="id" type="BIGINT" autoIncrement="true"> <column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/> <constraints primaryKey="true" nullable="false"/>
</column> </column>
<column name="user_id" type="BIGINT"> <column name="employee_id" type="BIGINT">
<constraints nullable="false" foreignKeyName="fk_employeeauth_employee" referencedTableName="employee" <constraints nullable="false" foreignKeyName="fk_employeeauth_employee" referencedTableName="employee"
referencedColumnNames="id"/> referencedColumnNames="id"/>
</column> </column>

View File

@ -5,7 +5,7 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="2025-02-18--0004-employee-authorities-data" author="okalugin"> <changeSet id="2025-02-19--0004-employee-authorities-data" author="okalugin">
<loadData tableName="employee_authorities" file="db.changelog/data/csv/2025-02-18--0004-employee-authorities-data.csv" <loadData tableName="employee_authorities" file="db.changelog/data/csv/2025-02-18--0004-employee-authorities-data.csv"
separator=";" separator=";"
quotchar='"' quotchar='"'

View File

@ -5,8 +5,8 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="2025-02-18--0005-employee-visits-data" author="okalugin"> <changeSet id="2025-02-18--0005-employee-entrances-data" author="okalugin">
<loadData tableName="employee_visits" file="db.changelog/data/csv/2025-02-18--0005-employee-visits-data.csv" <loadData tableName="employee_entrances" file="db.changelog/data/csv/2025-02-18--0005-employee-entrances-data.csv"
separator=";" separator=";"
quotchar='"' quotchar='"'
encoding="UTF-8"/> encoding="UTF-8"/>

View File

@ -1,6 +1,6 @@
id;value;is_active id;value;name
1;1234567890123456789;true 1;1234567890123456789;Главный Вход
2;9223372036854775807;true 2;9223372036854775807;Задний Вход
3;1122334455667788990;false 3;1122334455667788990;Вход с парковки
4;998877665544332211;false 4;998877665544332211;Вход с улицы Колатушкина
5;5566778899001122334;true 5;5566778899001122334;Вход с улицы Пушкина
1 id value is_active name
2 1 1234567890123456789 true Главный Вход
3 2 9223372036854775807 true Задний Вход
4 3 1122334455667788990 false Вход с парковки
5 4 998877665544332211 false Вход с улицы Колатушкина
6 5 5566778899001122334 true Вход с улицы Пушкина

View File

@ -1,5 +1,5 @@
login;password;name;photo_url;position login;password;name;photo_url;position;is_enabled
pivanov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Иванов Петр Федорович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик pivanov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Иванов Петр Федорович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик;true
ipetrov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Петров Иван Константинович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Аналитик ipetrov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Петров Иван Константинович;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Аналитик;false
asemenov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Семенов Анатолий Анатольевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик asemenov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Семенов Анатолий Анатольевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Разработчик;true
afedorov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Федоров Александр Сергеевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Тестировщик afedorov;$2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK;Федоров Александр Сергеевич;https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg;Тестировщик;true
1 login password name photo_url position is_enabled
2 pivanov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Иванов Петр Федорович https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Разработчик true
3 ipetrov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Петров Иван Константинович https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Аналитик false
4 asemenov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Семенов Анатолий Анатольевич https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Разработчик true
5 afedorov $2a$10$Jzb9I5eeHC0UIn/q5Rhq..wkI7KicBEZKB2u5BvnH8.n12d4alTOK Федоров Александр Сергеевич https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg Тестировщик true

View File

@ -1,5 +1,5 @@
employee_id;authorities_id employee_id;authorities_id
1;1 1;2
2;2 2;1
3;2 3;1
4;2 4;1
1 employee_id authorities_id
2 1 1 2
3 2 2 1
4 3 2 1
5 4 2 1

View File

@ -0,0 +1,2 @@
employee_id;visit_time;reader;type
1;2024-02-12T08:30:00;1;smartphone
1 employee_id visit_time reader type
2 1 2024-02-12T08:30:00 1 smartphone

View File

@ -1,2 +0,0 @@
user_id;visit_time;reader;type
1;2024-02-12T08:30:00;1;smartphone
1 user_id visit_time reader type
2 1 2024-02-12T08:30:00 1 smartphone

View File

@ -8,12 +8,12 @@
<include file="db.changelog/1.0/2024-10-20--0002-employee.xml"/> <include file="db.changelog/1.0/2024-10-20--0002-employee.xml"/>
<include file="db.changelog/1.0/2025-02-18--0003-authority.xml"/> <include file="db.changelog/1.0/2025-02-18--0003-authority.xml"/>
<include file="db.changelog/1.0/2025-02-18--0004-employee-authorities.xml"/> <include file="db.changelog/1.0/2025-02-18--0004-employee-authorities.xml"/>
<include file="/db.changelog/1.0/2025-02-18--0005-employee-visits.xml"/> <include file="/db.changelog/1.0/2025-02-18--0005-employee-entrances.xml"/>
<include file="db.changelog/data/2024-10-20--0001-code-data.xml"/> <include file="db.changelog/data/2024-10-20--0001-code-data.xml"/>
<include file="db.changelog/data/2024-10-20--0002-employee-data.xml"/> <include file="db.changelog/data/2024-10-20--0002-employee-data.xml"/>
<include file="db.changelog/data/2025-02-18--0003-authority-data.xml"/> <include file="db.changelog/data/2025-02-18--0003-authority-data.xml"/>
<include file="db.changelog/data/2025-02-18--0004-employee-authorities-data.xml"/> <include file="db.changelog/data/2025-02-18--0004-employee-authorities-data.xml"/>
<include file="/db.changelog/data/2025-02-18--0005-employee-visits-data.xml"/> <include file="/db.changelog/data/2025-02-18--0005-employee-entrances-data.xml"/>
</databaseChangeLog> </databaseChangeLog>