update
This commit is contained in:
@@ -1,48 +1,48 @@
|
||||
package com.walkguide.config;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.walkguide.entity.User;
|
||||
import com.walkguide.repository.UserRepository;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DataSeeder implements CommandLineRunner {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
// Mesin enkripsi password
|
||||
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
|
||||
// Ngecek kalau tabel users kosong, baru diisi
|
||||
if (userRepository.count() == 0) {
|
||||
|
||||
// 1. Bikin akun Guardian (Pendamping)
|
||||
|
||||
// 1. Buat Guardian (tanpa connected_to dulu)
|
||||
User guardian = User.builder()
|
||||
.email("guardian@walkguide.com")
|
||||
.password(passwordEncoder.encode("guardian123")) // Password barunya
|
||||
.role("ROLE_GUARDIAN") // Role udah diganti
|
||||
.password(passwordEncoder.encode("guardian123"))
|
||||
.role("ROLE_GUARDIAN")
|
||||
.build();
|
||||
guardian = userRepository.save(guardian);
|
||||
|
||||
// 2. Bikin akun User (Tunanetra)
|
||||
// 2. Buat User Tunanetra, langsung sambungkan ke Guardian
|
||||
User user = User.builder()
|
||||
.email("user@walkguide.com")
|
||||
.password(passwordEncoder.encode("user123"))
|
||||
.role("ROLE_USER")
|
||||
.connectedTo(guardian)
|
||||
.build();
|
||||
user = userRepository.save(user);
|
||||
|
||||
// Simpan ke database
|
||||
// 3. Update Guardian -> sambungkan balik ke User yang dijaganya
|
||||
guardian.setConnectedTo(user);
|
||||
userRepository.save(guardian);
|
||||
userRepository.save(user);
|
||||
|
||||
System.out.println("✅ Data Seeder berhasil: Akun Guardian dan User telah masuk ke Database!");
|
||||
|
||||
System.out.println("DataSeeder: Guardian (" + guardian.getId()
|
||||
+ ") <-> User (" + user.getId() + ") berhasil dihubungkan!");
|
||||
} else {
|
||||
System.out.println("DataSeeder: Database sudah ada data, skip seeding.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
-11
@@ -1,7 +1,12 @@
|
||||
package com.walkguide.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.walkguide.dto.ApiResponse;
|
||||
import com.walkguide.entity.User;
|
||||
import com.walkguide.repository.UserRepository;
|
||||
import com.walkguide.security.JwtUtil;
|
||||
import com.walkguide.service.MockDataService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
@@ -9,10 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.walkguide.dto.ApiResponse;
|
||||
import com.walkguide.service.MockDataService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/guardian")
|
||||
@@ -20,24 +22,56 @@ import lombok.RequiredArgsConstructor;
|
||||
public class GuardianController {
|
||||
|
||||
private final MockDataService mockDataService;
|
||||
private final UserRepository userRepository;
|
||||
private final JwtUtil jwtUtil;
|
||||
|
||||
// 4. Ambil Status User
|
||||
// 4. Ambil Status User yang dimonitor
|
||||
@GetMapping("/user-status")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> getUserStatus() {
|
||||
return ResponseEntity.ok(new ApiResponse<>(true, mockDataService.getUserStatus(), "Data status user berhasil diambil"));
|
||||
return ResponseEntity.ok(new ApiResponse<>(true,
|
||||
mockDataService.getUserStatus(),
|
||||
"Data status user berhasil diambil"));
|
||||
}
|
||||
|
||||
// 5. Setting Hardware Shortcut
|
||||
@PutMapping("/settings/shortcuts")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> updateShortcuts(@RequestBody Map<String, Object> request) {
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> updateShortcuts(
|
||||
@RequestBody Map<String, Object> request) {
|
||||
Map<String, Object> updated = mockDataService.updateShortcuts(request);
|
||||
return ResponseEntity.ok(new ApiResponse<>(true, updated, "Shortcut berhasil diperbarui"));
|
||||
}
|
||||
|
||||
// 6. Setting Sensitivitas AI
|
||||
@PutMapping("/settings/ai")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> updateAiSettings(@RequestBody Map<String, Object> request) {
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> updateAiSettings(
|
||||
@RequestBody Map<String, Object> request) {
|
||||
Map<String, Object> updated = mockDataService.updateAiSettings(request);
|
||||
return ResponseEntity.ok(new ApiResponse<>(true, updated, "Setting AI berhasil diperbarui"));
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Lihat User yang terhubung ke Guardian ini
|
||||
@GetMapping("/my-user")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> getMyConnectedUser(
|
||||
HttpServletRequest request) {
|
||||
String token = request.getHeader("Authorization").substring(7);
|
||||
String email = jwtUtil.extractUsername(token);
|
||||
|
||||
User guardian = userRepository.findByEmail(email)
|
||||
.orElseThrow(() -> new RuntimeException("Guardian tidak ditemukan"));
|
||||
|
||||
User connectedUser = guardian.getConnectedTo();
|
||||
if (connectedUser == null) {
|
||||
return ResponseEntity.ok(new ApiResponse<>(true,
|
||||
Map.of("message", "Belum ada user yang terhubung"),
|
||||
"Tidak ada koneksi"));
|
||||
}
|
||||
|
||||
Map<String, Object> data = Map.of(
|
||||
"userId", connectedUser.getId(),
|
||||
"userEmail", connectedUser.getEmail(),
|
||||
"connectedSince", connectedUser.getCreatedAt().toString()
|
||||
);
|
||||
return ResponseEntity.ok(new ApiResponse<>(true, data,
|
||||
"Data user yang dipantau berhasil diambil"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,60 @@
|
||||
package com.walkguide.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.walkguide.dto.ApiResponse;
|
||||
import com.walkguide.entity.User;
|
||||
import com.walkguide.repository.UserRepository;
|
||||
import com.walkguide.security.JwtUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.walkguide.dto.ApiResponse;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/user")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
// 7. Sinyal Darurat (Voice Command)
|
||||
private final UserRepository userRepository;
|
||||
private final JwtUtil jwtUtil;
|
||||
|
||||
// Sinyal Darurat (Voice Command)
|
||||
@PostMapping("/emergency")
|
||||
public ResponseEntity<ApiResponse<String>> triggerEmergency(@RequestBody Map<String, Object> request) {
|
||||
// Simulasi mengirim notif ke Guardian
|
||||
public ResponseEntity<ApiResponse<String>> triggerEmergency(
|
||||
@RequestBody Map<String, Object> request) {
|
||||
String triggerType = (String) request.get("triggerType");
|
||||
return ResponseEntity.ok(new ApiResponse<>(true, "Darurat Terkirim", "Guardian telah diberi peringatan via: " + triggerType));
|
||||
return ResponseEntity.ok(new ApiResponse<>(true,
|
||||
"Darurat Terkirim",
|
||||
"Guardian telah diberi peringatan via: " + triggerType));
|
||||
}
|
||||
}
|
||||
|
||||
// Lihat Guardian yang terhubung ke User ini
|
||||
@GetMapping("/my-guardian")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> getMyGuardian(
|
||||
HttpServletRequest request) {
|
||||
String token = request.getHeader("Authorization").substring(7);
|
||||
String email = jwtUtil.extractUsername(token);
|
||||
|
||||
User user = userRepository.findByEmail(email)
|
||||
.orElseThrow(() -> new RuntimeException("User tidak ditemukan"));
|
||||
|
||||
User guardian = user.getConnectedTo();
|
||||
if (guardian == null) {
|
||||
return ResponseEntity.ok(new ApiResponse<>(true,
|
||||
Map.of("message", "Belum ada guardian yang terhubung"),
|
||||
"Tidak ada koneksi"));
|
||||
}
|
||||
|
||||
Map<String, Object> data = Map.of(
|
||||
"guardianId", guardian.getId(),
|
||||
"guardianEmail", guardian.getEmail()
|
||||
);
|
||||
return ResponseEntity.ok(new ApiResponse<>(true, data,
|
||||
"Data guardian berhasil diambil"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,22 @@ package com.walkguide.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
@Data
|
||||
@@ -18,20 +25,39 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class User {
|
||||
|
||||
// Ini otomatis bikin ID angka urut (1, 2, 3, dst)
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
// Email gak boleh kosong dan gak boleh ada yang kembar
|
||||
@Column(unique = true, nullable = false)
|
||||
private String email;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String password;
|
||||
|
||||
// Buat nandain dia ini ROLE_USER atau ROLE_ADMIN
|
||||
@Column(nullable = false)
|
||||
private String role;
|
||||
}
|
||||
private String role;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "connected_to")
|
||||
private User connectedTo;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private Instant createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private Instant updatedAt;
|
||||
|
||||
@PrePersist
|
||||
public void onCreate() {
|
||||
Instant now = Instant.now();
|
||||
this.createdAt = now;
|
||||
this.updatedAt = now;
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
public void onUpdate() {
|
||||
this.updatedAt = Instant.now();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
package com.walkguide.repository;
|
||||
|
||||
import com.walkguide.entity.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.walkguide.entity.User;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
// Ini fungsi ajaib Spring Boot. Cuma dari nama fungsinya aja,
|
||||
// dia udah tau maksudnya "Tolong cariin user di database yang emailnya = X"
|
||||
|
||||
Optional<User> findByEmail(String email);
|
||||
}
|
||||
|
||||
@Query("SELECT u FROM User u WHERE u.connectedTo.id = :guardianId AND u.role = 'ROLE_USER'")
|
||||
Optional<User> findUserByGuardianId(@Param("guardianId") Long guardianId);
|
||||
|
||||
@Query("SELECT u FROM User u WHERE u.connectedTo.id = :userId AND u.role = 'ROLE_GUARDIAN'")
|
||||
Optional<User> findGuardianByUserId(@Param("userId") Long userId);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
# Server Port
|
||||
# ===== SERVER =====
|
||||
server.port=8080
|
||||
|
||||
# === KONEKSI H2 VIRTUAL (GAK PAKE PASSWORD) ===
|
||||
spring.datasource.url=jdbc:h2:mem:walkguidedb
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||
# ===== POSTGRESQL CONNECTION =====
|
||||
spring.datasource.url=jdbc:postgresql://202.46.28.160:2002/uas_5803024001
|
||||
spring.datasource.username=5803024001
|
||||
spring.datasource.password=pw5803024001
|
||||
spring.datasource.driver-class-name=org.postgresql.Driver
|
||||
|
||||
# Biar Spring Boot otomatis bikin tabel
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
# ===== JPA / HIBERNATE =====
|
||||
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
|
||||
spring.jpa.hibernate.ddl-auto=validate
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.format_sql=true
|
||||
|
||||
# JWT Configuration
|
||||
jwt.secret=WalkGuideSecretKeyYangSangatPanjangMinimal256BitUntukKeamananWalkGuide
|
||||
jwt.expiration=86400000
|
||||
# ===== FLYWAY =====
|
||||
spring.flyway.enabled=true
|
||||
spring.flyway.locations=classpath:db/migration
|
||||
spring.flyway.baseline-on-migrate=true
|
||||
|
||||
# ===== JWT =====
|
||||
jwt.secret=404E635266556A586E3272357538782F413F4428472B4B6250645367566B5970
|
||||
jwt.expiration=86400000
|
||||
|
||||
# ===== SWAGGER =====
|
||||
springdoc.swagger-ui.path=/swagger-ui.html
|
||||
springdoc.api-docs.path=/v3/api-docs
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
-- V1__create_users_table.sql
|
||||
-- Membuat tabel users dengan relasi self-referencing guardian <-> user
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(50) NOT NULL,
|
||||
connected_to BIGINT REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_connected_to ON users(connected_to);
|
||||
@@ -0,0 +1,22 @@
|
||||
-- V2__seed_users.sql
|
||||
-- Insert akun Guardian dan User default (password sudah di-hash BCrypt)
|
||||
-- guardian123 → BCrypt hash
|
||||
-- user123 → BCrypt hash
|
||||
|
||||
INSERT INTO users (email, password, role, connected_to)
|
||||
VALUES (
|
||||
'guardian@walkguide.com',
|
||||
'$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt6WKGK', -- guardian123
|
||||
'ROLE_GUARDIAN',
|
||||
NULL -- akan di-update setelah user dibuat
|
||||
)
|
||||
ON CONFLICT (email) DO NOTHING;
|
||||
|
||||
INSERT INTO users (email, password, role, connected_to)
|
||||
VALUES (
|
||||
'user@walkguide.com',
|
||||
'$2a$10$TJ.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt6WK', -- user123
|
||||
'ROLE_USER',
|
||||
NULL
|
||||
)
|
||||
ON CONFLICT (email) DO NOTHING;
|
||||
@@ -0,0 +1,18 @@
|
||||
-- V2__link_guardian_user.sql
|
||||
-- Menghubungkan Guardian <-> User setelah DataSeeder Java insert kedua akun
|
||||
-- Script ini dijalankan SETELAH aplikasi sudah seed data via DataSeeder.java
|
||||
-- Jika DataSeeder yang handle relasi, migration ini bisa jadi no-op safety net
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_guardian_id BIGINT;
|
||||
v_user_id BIGINT;
|
||||
BEGIN
|
||||
SELECT id INTO v_guardian_id FROM users WHERE email = 'guardian@walkguide.com';
|
||||
SELECT id INTO v_user_id FROM users WHERE email = 'user@walkguide.com';
|
||||
|
||||
IF v_guardian_id IS NOT NULL AND v_user_id IS NOT NULL THEN
|
||||
UPDATE users SET connected_to = v_user_id WHERE id = v_guardian_id;
|
||||
UPDATE users SET connected_to = v_guardian_id WHERE id = v_user_id;
|
||||
END IF;
|
||||
END $$;
|
||||
Reference in New Issue
Block a user