Skip to content

Commit

Permalink
Merge branch 'main' into feature/フロントエンドの結合テストを実装
Browse files Browse the repository at this point in the history
  • Loading branch information
KentaHizume authored Jan 29, 2025
2 parents 6084682 + 505ab6f commit 471459f
Show file tree
Hide file tree
Showing 66 changed files with 660 additions and 704 deletions.
18 changes: 18 additions & 0 deletions documents/contents/guidebooks/conventions/coding-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,21 @@ SpotBugs を利用して、 SpotBugs が提供するバグパターンに該当
- [SpotBugs プラグイン](../how-to-develop/java/common-project-settings.md#spotbugs-plugin)
- [Java formatting and linting :material-open-in-new:](https://code.visualstudio.com/docs/java/java-linting){ target=_blank }
- [静的コード分析とフォーマット(Vue.js)](../how-to-develop/vue-js/static-verification-and-format.md)

## AlesInfiny Maia でカスタマイズしている規約 {#custom-conventions}

AlesInfiny Maia では上記に示した基本のコーディング規約に加えて、以下に示すカスタマイズした規約を採用しています。

- Java アプリケーション

- Checkstyle プラグイン

Checkstyle の規約をカスタマイズする場合、 Checkstyle プラグインが読み込むインプットファイルを編集します。具体的な方法については [こちら](../how-to-develop/java/common-project-settings.md#checkstyle-plugin) を参照ください。
Checkstyle プラグインでカスタマイズする規約は以下の通りです。

- [IllegalCatch :material-open-in-new:](https://checkstyle.sourceforge.io/checks/coding/illegalcatch.html){ target=_blank }

汎用検査例外を含む特定の例外のキャッチを禁止します。

汎用的な例外をキャッチしてしまうと、具体的な例外が隠蔽されてしまい、原因の特定が難しくなります。
汎用的な例外ではなく、具体的な例外のみをキャッチするように本規約を設けます。
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,6 @@
<property name="exceptionVariableName" value="expected"/>
</module>
<module name="CommentsIndentation"/>
<module name="IllegalCatch"/>
</module>
</module>
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
<suppress checks=".*" files="com[\\/]dressca[\\/]infrastructure[\\/]repository[\\/]mybatis[\\/]generated"/>
<!-- テストクラスのメソッド名はチェックしない(日本語を使用するため) -->
<suppress checks="MethodName" files=".*Test.java$"/>
<!-- テストクラスでは汎用的な例外のキャッチを禁止しない -->
<suppress checks="IllegalCatch" files=".*Test.java$"/>
</suppressions>
16 changes: 7 additions & 9 deletions samples/azure-ad-b2c-sample/auth-frontend/app/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { authenticationService } from '@/services/authentication/authentication-service';
import { fetchServerTime } from '@/services/server-time/server-time-service';
import { fetchUser } from './services/user/user-service';
Expand All @@ -8,8 +9,11 @@ import { useUserStore } from './stores/user/user';
import { useAuthenticationStore } from './stores/authentication/authentication';
const userStore = useUserStore();
const { getUserId } = storeToRefs(userStore);
const serverTimeStore = useServerTimeStore();
const { getServerTime } = storeToRefs(serverTimeStore);
const authenticationStore = useAuthenticationStore();
const { isAuthenticated } = storeToRefs(authenticationStore);
const signIn = async () => {
await authenticationService.signInAzureADB2C();
Expand All @@ -28,19 +32,13 @@ onMounted(async () => {
<template>
<header><h1>Azure AD B2C 認証サンプル</h1></header>
<div>
<span>現在時刻: {{ serverTimeStore.getServerTime }}</span>
<span>現在時刻: {{ getServerTime }}</span>
<button type="submit" @click="updateServerTime()">更新</button>
</div>
<div>
<button
v-if="!authenticationStore.isAuthenticated"
type="submit"
@click="signIn()"
>
<button v-if="!isAuthenticated" type="submit" @click="signIn()">
ログイン
</button>
<span v-if="authenticationStore.isAuthenticated"
>ユーザーID: {{ userStore.getUserId }}</span
>
<span v-if="isAuthenticated">ユーザーID: {{ getUserId }}</span>
</div>
</template>
3 changes: 3 additions & 0 deletions samples/azure-ad-b2c-sample/auth-frontend/app/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import { globalErrorHandler } from './shared/error-handler/global-error-handler';

const app = createApp(App);

app.use(createPinia());

app.use(globalErrorHandler);

app.mount('#app');
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { App, ComponentPublicInstance } from 'vue';

export const globalErrorHandler = {
/* eslint no-param-reassign: 0 */
install(app: App) {
app.config.errorHandler = (
err: unknown,
instance: ComponentPublicInstance | null,
info: string,
) => {
// 本サンプルAPではコンソールへログの出力を行います。
// APの要件によってはサーバーやログ収集ツールにログを送信し、エラーを握りつぶすこともあります。
/* eslint no-console: 0 */
console.log(err, instance, info);
};

// Vue.js 以外のエラー
// テストやデバッグ時にエラーの発生を検知するために利用します。
window.addEventListener('error', (event) => {
/* eslint no-console: 0 */
console.log(event);
});

// テストやデバッグ時に予期せぬ非同期エラーの発生を検知するために利用します。
window.addEventListener('unhandledrejection', (event) => {
/* eslint no-console: 0 */
console.log(event);
});
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.dressca.applicationcore.applicationservice;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Locale;
import org.slf4j.Logger;
Expand Down Expand Up @@ -171,7 +171,7 @@ public CatalogItem addItemToCatalog(String name, String description, BigDecimal

CatalogItem item = CatalogItem.createCatalogItemForRegistration(name, description, price, productCode,
catalogCategoryId, catalogBrandId);
item.setRowVersion(LocalDateTime.now());
item.setRowVersion(OffsetDateTime.now());
CatalogItem catalogItemAdded = this.catalogRepository.add(item);
return catalogItemAdded;
}
Expand All @@ -185,7 +185,7 @@ public CatalogItem addItemToCatalog(String name, String description, BigDecimal
* @throws CatalogNotFoundException 削除対象のカタログアイテムが存在しなかった場合。
* @throws OptimisticLockingFailureException 楽観ロックエラーの場合。
*/
public void deleteItemFromCatalog(long id, LocalDateTime rowVersion)
public void deleteItemFromCatalog(long id, OffsetDateTime rowVersion)
throws PermissionDeniedException, CatalogNotFoundException, OptimisticLockingFailureException {
apLog.debug(messages.getMessage(MessageIdConstants.D_CATALOG_DELETE_ITEM_FROM_CATALOG, new Object[] { id },
Locale.getDefault()));
Expand Down Expand Up @@ -219,7 +219,7 @@ public void deleteItemFromCatalog(long id, LocalDateTime rowVersion)
* @throws OptimisticLockingFailureException 楽観ロックエラーの場合。
*/
public void updateCatalogItem(long id, String name, String description, BigDecimal price, String productCode,
long catalogCategoryId, long catalogBrandId, LocalDateTime rowVersion)
long catalogCategoryId, long catalogBrandId, OffsetDateTime rowVersion)
throws CatalogNotFoundException, PermissionDeniedException, CatalogCategoryNotFoundException,
CatalogBrandNotFoundException, OptimisticLockingFailureException {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.dressca.applicationcore.catalog;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
Expand All @@ -28,7 +28,7 @@ public class CatalogItem {
private String productCode;
private long catalogCategoryId;
private long catalogBrandId;
private LocalDateTime rowVersion;
private OffsetDateTime rowVersion;

/**
* {@link CatalogItem} クラスのインスタンスを初期化します。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.dressca.applicationcore.catalog;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.List;

/**
Expand Down Expand Up @@ -76,7 +76,7 @@ List<CatalogItem> findByBrandIdAndCategoryId(long brandId, long categoryId, int
* @param rowVersion 行バージョン。
* @return 削除できたら 1 、できなければ 0 を返す。
*/
int remove(Long id, LocalDateTime rowVersion);
int remove(Long id, OffsetDateTime rowVersion);

/**
* カタログアイテムを更新します。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
import static org.mockito.Mockito.when;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -346,7 +347,7 @@ void setUp() {
long targetId = 1L;
when(this.userStore.isInRole(anyString())).thenReturn(true);
when(this.catalogDomainService.existCatalogItem(targetId)).thenReturn(true);
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
when(this.catalogRepository.remove(targetId, rowVersion)).thenReturn(1);

// Action
Expand All @@ -362,7 +363,7 @@ void setUp() {
long targetId = 999L;
when(this.userStore.isInRole(anyString())).thenReturn(true);
when(this.catalogDomainService.existCatalogItem(targetId)).thenReturn(false);
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
when(this.catalogRepository.remove(targetId, rowVersion)).thenReturn(1);

// Action
Expand All @@ -380,7 +381,7 @@ void setUp() {
long targetId = 1L;
when(this.userStore.isInRole(anyString())).thenReturn(false);
when(this.catalogDomainService.existCatalogItem(targetId)).thenReturn(true);
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
when(this.catalogRepository.remove(targetId, rowVersion)).thenReturn(1);

// Action
Expand All @@ -398,7 +399,7 @@ void setUp() {
long targetId = 1L;
when(this.userStore.isInRole(anyString())).thenReturn(true);
when(this.catalogDomainService.existCatalogItem(targetId)).thenReturn(true);
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
when(this.catalogRepository.remove(targetId, rowVersion)).thenReturn(0);

// Action
Expand Down Expand Up @@ -426,7 +427,7 @@ void setUp() {
String description = "Description.";
BigDecimal price = BigDecimal.valueOf(100_000_000L);
String productCode = "C000000001";
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);

// Action
this.service.updateCatalogItem(targetId, name, description, price, productCode, categoryId, brandId, rowVersion);
Expand All @@ -450,7 +451,7 @@ void setUp() {
String description = "Description.";
BigDecimal price = BigDecimal.valueOf(100_000_000L);
String productCode = "C000000001";
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);

// Action
Executable action = () -> {
Expand All @@ -476,7 +477,7 @@ void setUp() {
String description = "Description.";
BigDecimal price = BigDecimal.valueOf(100_000_000L);
String productCode = "C000000001";
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);

// Action
Executable action = () -> {
Expand All @@ -502,7 +503,7 @@ void setUp() {
String description = "Description.";
BigDecimal price = BigDecimal.valueOf(100_000_000L);
String productCode = "C000000001";
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);

// Action
Executable action = () -> {
Expand All @@ -528,7 +529,7 @@ void setUp() {
String description = "Description.";
BigDecimal price = BigDecimal.valueOf(100_000_000L);
String productCode = "C000000001";
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);

// Action
Executable action = () -> {
Expand All @@ -554,7 +555,7 @@ void setUp() {
String description = "Description.";
BigDecimal price = BigDecimal.valueOf(100_000_000L);
String productCode = "C000000001";
LocalDateTime rowVersion = LocalDateTime.of(2024, 1, 1, 0, 0, 0, 0);
OffsetDateTime rowVersion = OffsetDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);

// Action
Executable action = () -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,6 @@
<property name="exceptionVariableName" value="expected"/>
</module>
<module name="CommentsIndentation"/>
<module name="IllegalCatch"/>
</module>
</module>
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
<suppress checks="MethodName" files=".*Test.java$"/>
<!-- メッセージクラスの文字数はチェックしない -->
<suppress checks="LineLength" files=".*MessageIdConstants.java$"/>
<!-- テストクラスでは汎用的な例外のキャッチを禁止しない -->
<suppress checks="IllegalCatch" files=".*Test.java$"/>
</suppressions>
49 changes: 46 additions & 3 deletions samples/web-csr/dressca-backend/infrastructure/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ tasks.named('test') {
bootJar.enabled = false
jar.enabled = true


// 正規表現と置換のペアをリストにまとめて置き換えを行うことで楽観ロックに対応します。
task updateMyBatisGeneratorMapperForOptimisticLocking {
doLast {

Expand All @@ -60,7 +62,7 @@ task updateMyBatisGeneratorMapperForOptimisticLocking {
// 楽観ロック制御を行う列名
def optimisticLockColumn = 'row_version'
// 楽観ロック制御を行う列のDB上のデータ型
def optimisticLockJdbcType = 'TIMESTAMP'
def optimisticLockJdbcType = 'TIMESTAMP_WITH_TIMEZONE'
// エンティティに変換した際の楽観ロック制御を行う列名
def optimisticLockVariable = toLowerCamelCase(optimisticLockColumn)

Expand All @@ -69,12 +71,53 @@ task updateMyBatisGeneratorMapperForOptimisticLocking {
def xmlFile = file(generatedDirectory + path)
def xmlContent = xmlFile.text

// 正規表現と置換のペアをリストにまとめる
// 正規表現と置換のペアのリスト
// 置き換えの処理は更新対象の検索方法が Example と PrimaryKey のどちらを利用するかで異なります。
def replacements = [

/* Exampleの場合、更新処理の set 句で指定する更新後の行バージョンの値を、メソッドの引数から現在時刻に置き換えます。
〇 置換前
<update id="updateByExampleSelective" parameterType="map">
<set>
<if test="row.rowVersion != null">
row_version = #{row.rowVersion,jdbcType=TIMESTAMP_WITH_TIMEZONE},
</if>
</set>
</update>
〇 置換後
<update id="updateByExampleSelective" parameterType="map">
<set>
<if test="row.rowVersion != null">
row_version = CURRENT_TIMESTAMP,
</if>
</set>
</update>
*/
[ /(<update id="updateByExampleSelective"[\s\S]*?)(${optimisticLockColumn} = \#\{row.${optimisticLockVariable},jdbcType=${optimisticLockJdbcType}},)/,
"\$1${optimisticLockColumn} = CURRENT_TIMESTAMP," ],
[ /(<update id="updateByExample"[\s\S]*?)(${optimisticLockColumn} = \#\{row.${optimisticLockVariable},jdbcType=${optimisticLockJdbcType}})/,
"\$1${optimisticLockColumn} = CURRENT_TIMESTAMP" ],

/* PrimaryKeyの場合、更新処理の set 句で指定する更新後の行バージョンの値を、メソッドの引数から現在時刻に置き換えます。
さらに、更新処理の対象を検索する where 句で指定する検索条件に行バージョンを追加します。
〇 置換前
<update id="updateByPrimaryKey" parameterType="com.dressca.infrastructure.repository.mybatis.generated.entity.CatalogItemEntity">
update catalog_items
set name = #{name,jdbcType=VARCHAR},
row_version = #{rowVersion,jdbcType=TIMESTAMP_WITH_TIMEZONE}
where id = #{id,jdbcType=BIGINT}
</update>
〇 置換後
<update id="updateByPrimaryKey" parameterType="com.dressca.infrastructure.repository.mybatis.generated.entity.CatalogItemEntity">
update catalog_items
set name = #{name,jdbcType=VARCHAR},
row_version = CURRENT_TIMESTAMP
where id = #{id,jdbcType=BIGINT}
and row_version = #{rowVersion,jdbcType=TIMESTAMP_WITH_TIMEZONE}
</update>
*/
[ /(<update id="updateByPrimaryKeySelective"[\s\S]*?)(${optimisticLockColumn} = \#\{${optimisticLockVariable},jdbcType=${optimisticLockJdbcType}},)/,
"\$1${optimisticLockColumn} = CURRENT_TIMESTAMP," ],
[ /(<update id="updateByPrimaryKeySelective"(?:(?!and ${optimisticLockColumn} = \#\{${optimisticLockVariable},jdbcType=${optimisticLockJdbcType}})[\s\S])*?)(<\/update>)/,
Expand Down Expand Up @@ -115,7 +158,7 @@ String toLowerCamelCase(String snakeCase) {
}
}

// 最初の文字を小文字にする
// 最初の文字を小文字にします
if (camelCase.length() > 0) {
camelCase.setCharAt(0, Character.toLowerCase(camelCase.charAt(0)))
}
Expand Down
Loading

0 comments on commit 471459f

Please sign in to comment.